Physics in OpenB3DMax?

Started by Cosmo, February 27, 2019, 16:31:02

Previous topic - Next topic

Cosmo

Do you have to do it yourself or is there some library I can use?

markcwm

Well, there were some physics wrappers written for Minib3d but the more complete ones were either restricted, like the demo for Itmbin's brightrealm wrapper or Windows only like JV-ODE physics. There are a few free Newton wrappers around but I haven't really looked into it, as physics is kind of last on my todo list. For a ready-to-use cross-platform physics solution I believe AGK2 is what many folks are using.

angros47

OpenB3D features also some physics features itself, since it allows to use constraints, and to bind an entity to some constrained pivots, to simulate a rigid body

markcwm

Hi Angelo,

nice to see you back at SyntaxBomb. Did you ever write a demo of how to correctly set up constraints? I couldn't figure out how to use them.

angros47

Here is an old quick and dirty example:

#include "openb3d.bi"




screen 18,  32, , &h10002


Graphics3d 640,480,32,1,1

var camera=createcamera(0)
var cube=createcube()


dim piv(8) as any ptr
for i as integer=1 to 8
piv(i)=createpivot()
entitytype piv(i),1
entityradius piv(i),.01
next

positionentity piv(1),-1,-1,-1
positionentity piv(2), 1,-1,-1
positionentity piv(3),-1, 1,-1
positionentity piv(4), 1, 1,-1
positionentity piv(5),-1,-1, 1
positionentity piv(6), 1,-1, 1
positionentity piv(7),-1, 1, 1
positionentity piv(8), 1, 1, 1



for i as integer=1 to 8
actvector piv(i),0,-.01,0
actnewtonian piv(i),.9
for i2 as integer=i+1 to 8
createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
next
next

createrigidbody cube,piv(1),piv(2),piv(3),piv(5)
fitmesh cube,0,0,0,1,1,1





var cube2=createcube()


dim piv2(8) as any ptr
for i as integer=1 to 8
piv2(i)=createpivot()
entitytype piv2(i),1
entityradius piv2(i),.01
next

positionentity piv2(1), 2,-1,-1
positionentity piv2(2), 4,-1,-1
positionentity piv2(3), 2, 1,-1
positionentity piv2(4), 4, 1,-1
positionentity piv2(5), 2,-1, 1
positionentity piv2(6), 4,-1, 1
positionentity piv2(7), 2, 1, 1
positionentity piv2(8), 4, 1, 1



for i as integer=1 to 8
actvector piv2(i),0,-.01,0
actnewtonian piv2(i),.9
for i2 as integer=i+1 to 8
createconstraint piv2(i),piv2(i2), entitydistance(piv2(i),piv2(i2))
next
next






createrigidbody cube2,piv2(1),piv2(2),piv2(3),piv2(5)
fitmesh cube2,0,0,0,1,1,1
updateworld
renderworld

entitytype cube,-2
entitytype cube2,-2

var plane=createplane()':scaleentity plane, 100,.1,100
entitytype plane,-2

moveentity plane,0,-4,15
entitycolor plane,255,0,0

collisions 1,2,1,3


var light=createlight()
positionentity light,5,5,5
pointentity light,cube
moveentity camera,0,2,-15
pointentity camera,cube

var s=createcube
positionentity s,3,-3,0
scaleentity s,2,1,2
entitytype s,-2
'turnentity plane,0,0,10

dim key as string
do




key=inkey
        if key=chr(255)+"H" then moveentity s,0,0,.1
        if key=chr(255)+"P" then moveentity s,0,0,-.1
        if key=chr(255)+"M" then moveentity s,.1,0,0
        if key=chr(255)+"K" then moveentity s,-.1,0,0
updateworld 1


renderworld
sleep 1
flip
flip
loop until key=chr(27)

markcwm

Hi  Angelo,

sorry for not replying to this in time, the example is quite impressive, but the boxes keep moving long after they should have stopped, so is there a way around this? Like a minimum friction or gravity thing.

Thanks.

angros47

In the line "actnewtonian piv(i),.9", try changing the ".9" to lower values, to simulate friction.
True friction against surfaces is not implemented, at the moment, that command simulates a generic "air friction". By the way, it could be possible to simulate a more compex friction, for example by checking if the entity is colliding with something and changing its action

markcwm

#7
Yes, that works, thanks. If the action values are set right it looks realistic. Hey, that's pretty cool using actions with constraints. But why does ActNewtonian need a smaller value to increase friction? I think it would be worth adding true friction based on collisions, a dynamic value would increase realism, maybe an entity weight would help.

angros47

It needs a smaller value because momentum is managed by measuring how much a entity has moved in the last step, and then moving it again along the same vector, by the previous amount of movement multiplied by a coefficient. A coefficient of 1 means perfect Newtonian momentum with no friction. A coefficient of 0 means no momentum. And so on.

A dynamic system would surely increase realism, but would make the library more complex (making it much slower) and less easy to learn. The reason I loved original Blitz3D is that it was simple and immediate, you could do almos everything with a single instruction. I tried to keep the same approach in new features

markcwm

I see, thanks for the explanation.

After some tests I find the problem was setting cube EntityType to 2, which was the same as the ground and caused the jittering, so you can use a newtonian value of .9. I agree there's no real need to make the library more complex for this, and it looks like users could just write collision-based friction outside the library.

Another problem, I notice the cubes half sink into the larger cube as they roll off it, I don't suppose there's a way to increase the precision of this type of collision? I tried adding constraints at halfway points, and adding constraints to the larger cube, but it didn't work.

angros47

To increase the precision you can add more halfway points (so far, there are eight halfway points, at the vertexes of the cube, but you can add more: one at the center of each face, for example). Then you must add constraints between them and the other ones, of course. The more points you add (and check for collisions) the more accurate collision will be (of course, you will increase the amount of calculations needed)

markcwm

Thanks. I added more constraints along each edge of the cube which is 12 and it worked, but I had to be careful adding constraints, just attaching all constraints to eachother caused a collapse, so primary constraints were attached first, then secondary constraints to both primary and secondary. It's not very noticeable and the cube still sinks into the base cube a little, but it is more realistic. Here's the example for Freebasic:
#include "openb3d.bi"

screen 18,  32, , &h10002


Graphics3d 640,480,32,0,2

var camera=createcamera(0)
var cube=createcube()
entitycolor cube,255,255,0

dim piv(20) as any ptr
for i as integer=1 to 20
piv(i)=createpivot()
entitytype piv(i),1
entityradius piv(i),.01
next

positionentity piv(1),-1,-1,-1
positionentity piv(2), 1,-1,-1
positionentity piv(3),-1, 1,-1
positionentity piv(4), 1, 1,-1
positionentity piv(5),-1,-1, 1
positionentity piv(6), 1,-1, 1
positionentity piv(7),-1, 1, 1
positionentity piv(8), 1, 1, 1

positionentity piv(9),-1,-1, 0
positionentity piv(10), 0,-1, 1
positionentity piv(11), 0,-1, 1
positionentity piv(12), 1,-1, 0
positionentity piv(13),-1, 1, 0
positionentity piv(14), 0, 1, 1
positionentity piv(15), 0, 1, 1
positionentity piv(16), 1, 1, 0
positionentity piv(17),-1, 0,-1
positionentity piv(18), 1, 0, 1
positionentity piv(19),-1, 0, 1
positionentity piv(20), 1, 0,-1

for i as integer=1 to 8
actvector piv(i),0,-.01,0
actnewtonian piv(i),.9
for i2 as integer=i to 8
if i<>i2 then
createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
endif
next
next

for i as integer=9 to 20
actvector piv(i),0,-.01,0
actnewtonian piv(i),.9
for i2 as integer=1 to 20
if i<>i2 then
createconstraint piv(i),piv(i2), entitydistance(piv(i),piv(i2))
endif
next
next

createrigidbody cube,piv(1),piv(2),piv(3),piv(5)
fitmesh cube,0,0,0,1,1,1

var cube2=createcube()

dim piv2(8) as any ptr
for i as integer=1 to 8
piv2(i)=createpivot()
entitytype piv2(i),1
entityradius piv2(i),.01
next

positionentity piv2(1), 2,-1,-1
positionentity piv2(2), 4,-1,-1
positionentity piv2(3), 2, 1,-1
positionentity piv2(4), 4, 1,-1
positionentity piv2(5), 2,-1, 1
positionentity piv2(6), 4,-1, 1
positionentity piv2(7), 2, 1, 1
positionentity piv2(8), 4, 1, 1

for i as integer=1 to 8
actvector piv2(i),0,-.01,0
actnewtonian piv2(i),.9
for i2 as integer=i+1 to 8
createconstraint piv2(i),piv2(i2), entitydistance(piv2(i),piv2(i2))
next
next

createrigidbody cube2,piv2(1),piv2(2),piv2(3),piv2(5)
fitmesh cube2,0,0,0,1,1,1

updateworld
renderworld

'entitytype cube,-2
'entitytype cube2,-2

var plane=createplane()':scaleentity plane, 100,.1,100
entitytype plane,-2

moveentity plane,0,-4,15
entitycolor plane,255,0,0

var light=createlight()
positionentity light,5,5,5
pointentity light,cube
moveentity camera,0,2,-15
pointentity camera,cube

var s=createcube
positionentity s,2,-3,0
scaleentity s,2,1,2
entitytype s,-2
'turnentity plane,0,0,10

collisions 1,2,1,3

dim key as string
do
key=inkey
        if key=chr(255)+"H" then moveentity s,0,0,.1
        if key=chr(255)+"P" then moveentity s,0,0,-.1
        if key=chr(255)+"M" then moveentity s,.1,0,0
        if key=chr(255)+"K" then moveentity s,-.1,0,0
updateworld 1


renderworld
sleep 1
flip
loop until key=chr(27)