blitz-research/monkey2

Can't access bullet module from rigidbody module

Opened this issue · 3 comments

Hi Mark,

Hope you're well.

Not sure if anything more is intended for mx2 now (suspect not?), but I'm attempting to add a New RigidBody method to pass in btRigidBodyConstructionInfo, inside modules/mojo3d/scene/components/rigidbody.monkey2.

However, on rebuilding mojo3d with the additional New below, mx2 doesn't complain, but the C++ compiler does...

	Method New( entity:Entity, constructionInfo:btRigidBodyConstructionInfo )
		
		Super.New( entity,Type )
		
		_btmotion=New MotionState( entity )
		
		_btbody=New btRigidBody( constructionInfo )
		
		Kinematic=False
		Restitution=0
		Friction=1
		RollingFriction=0
		CollisionGroup=1
		CollisionMask=1
		
		AddInstance()
	End

Error message suggests it can't locate btRigidBodyConstructionInfo on the C++ side (mx2 doesn't seem to mind!)...

Mx2cc version 1.1.15

***** Making module 'mojo3d' (windows release x64 msvc mx) *****

Parsing...
Semanting...
Translating...
Compiling...
Build error: System command failed:

cl -c -EHs -W0 -MT -utf-8 -bigobj -O2 -DNDEBUG -I"D:/DevTools/Monkey2/monkey2/modules/" -I"D:/DevTools/Monkey2/monkey2/modules/monkey/native" -I"D:/DevTools/Monkey2/monkey2/modules/bullet/bullet3-2.85.1/src/" -I"D:/DevTools/Monkey2/monkey2/modules/freetype/freetype-2.6.3/include/" -I"D:/DevTools/Monkey2/monkey2/modules/openal/openal-soft/include/" -I"D:/DevTools/Monkey2/monkey2/modules/sdl2/SDL/include/" -I"D:/DevTools/Monkey2/monkey2/modules/zlib/zlib-1.2.11/" -DNDEBUG=1 -DBB_THREADS=1 -showIncludes -Fo"D:/DevTools/Monkey2/monkey2/modules/mojo3d/mojo3d.buildv1.1.15/windows_release_msvc_x64_mx/build/jointfa856ede.cpp.obj" "D:/DevTools/Monkey2/monkey2/modules/mojo3d/mojo3d.buildv1.1.15/windows_release_msvc_x64_mx/src/mojo3d_scene_2components_2joint.cpp" >tmp/stdout1.txt

mojo3d_scene_2components_2joint.cpp
D:/DevTools/Monkey2/monkey2/modules/mojo3d/mojo3d.buildv1.1.15/windows_release_msvc_x64_mx/include/mojo3d_scene_2components_2rigidbody.h(61): error C2061: syntax error: identifier 'btRigidBodyConstructionInfo'
D:/DevTools/Monkey2/monkey2/modules/mojo3d/mojo3d.buildv1.1.15/windows_release_msvc_x64_mx/include/mojo3d_scene_2components_2rigidbody.h(63): error C2535: 't_mojo3d_RigidBody::t_mojo3d_RigidBody(t_mojo3d_Entity *)': member function already defined or declared
D:/DevTools/Monkey2/monkey2/modules/mojo3d/mojo3d.buildv1.1.15/windows_release_msvc_x64_mx/include/mojo3d_scene_2components_2rigidbody.h(61): note: see declaration of 't_mojo3d_RigidBody::t_mojo3d_RigidBody'

Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26730 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.



***** Fatal mx2cc error *****

Internal mx2cc build error

Update modules failed.
Total time elapsed: 0 m 3 s.

I've tried amending to:

Method New( entity:Entity, constructionInfo:bullet.btRigidBodyConstructionInfo )

... but this fails with:

Mx2cc version 1.1.15

***** Making module 'mojo3d' (windows release x64 msvc mx) *****

Parsing...
Semanting...
D:/DevTools/Monkey2/monkey2/modules/mojo3d/scene/components/rigidbody.monkey2 [84] : Error : Type 'mojo3d.bullet' has no member type named 'btRigidBodyConstructionInfo'

Update modules failed.
Total time elapsed: 0 m 1 s.

... like it's trying to access mojo3d.bullet instead of the base bullet module. I can't see any way to specify the base bullet module in the docs either, rather than looking in the current namespace.

Is there any way to do this?

(Also, how officially dead or otherwise is mx2?? I see SDL was recently updated!)

Ok, this is really an issue with the bullet module, you'll need to change line 505 of modules/bullet/bullet.monkey2 to:

btRigidBody::btRigidBodyConstructionInfo

However, I don't really recommend doing this. The constructioninfo will be passed by value in monkey2 which will be slow-ish without hackery. Your code also wont work 'as is' as you need to pass a MotionState via the constructioninfo. There's quite a bit of hackery involved in MotionStates too so I have no idea how easy that will be.

Can I ask why you want to do this? If you want to just create a RigidBody with some 'stock' settings, how about attaching one to a hidden entity and copying it when you need a new one?

I was actually just trying to figure out how to use btCompoundShape! I've since lost my logic, as I was trying to create my own RigidBody type, needing a constructioninfo, but I now think it's more about the collider... but now on looking through collider.monkey I'm even more confused. I see reference to btCompoundShape/addChildShape in the protected SetOrigin, but I don't really get what it's doing.

Basically wanted to create joined-up bodies, eg. tall cylinder with cone on top to represent a combined rocket body, perhaps a few cylinders for rocket engines. Using joints doesn't really work as they're always flexible (you can't make a 'solid' joint).

Reference here from the bullet author

I attempted it with this (see *** COMPOUND SHAPE ***), but the shapes clearly aren't locked together when they hit the ground:

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	Field _ground:Model
	'Field _donut:Model
	Field box1:Model
	Field box2:Model
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		'create ground
		Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
		Local groundMaterial:=New PbrMaterial( Color.Lime )
		_ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
		_ground.CastsShadow=False

		Local gcol:BoxCollider = _ground.AddComponent <BoxCollider> ()
		
		gcol.Box = groundBox
		
		Local gbody:RigidBody = _ground.AddComponent <RigidBody> ()
		gbody.Mass = 0
		
		
		'create donut
	'	Local donutMaterial:=New PbrMaterial( Color.Red, 0.05, 0.2 )
	'	_donut=Model.CreateTorus( 2,.5,48,24,donutMaterial )
	'	_donut.Move( 0,2.5,0 )
	
		Local geom:Boxf = New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)
		
		box1 = Model.CreateBox (geom, 2, 2, 2, New PbrMaterial (Color.Red))
		box1.Move (-1, 5, 0)
		box1.Rotate (Rnd (360), Rnd (360), Rnd (360))
		
		box2 = Model.CreateBox (geom, 2, 2, 2, New PbrMaterial (Color.Green))
		box2.Move (1, 4, 0)
		box2.Rotate (Rnd (360), Rnd (360), Rnd (360))
	
		Local col1:BoxCollider = box1.AddComponent <BoxCollider> ()
		col1.Box = geom
		
		Local col2:BoxCollider = box2.AddComponent <BoxCollider> ()
		col2.Box = geom
		
		box1.AddComponent <RigidBody> ()
		box2.AddComponent <RigidBody> ()
		
		' *** COMPOUND SHAPE ***
		
		Local btc:bullet.btCompoundShape = New bullet.btCompoundShape ()
		
		btc.addChildShape (Null, col1.Validate ())
		btc.addChildShape (Null, col2.Validate ())
		
		' https://stackoverflow.com/questions/27760983/btcompoundshape-added-extra-shape
		
		' New rigidbody with own construction info?
		
	End
	
	Method OnRender( canvas:Canvas ) Override
		
		If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
		
		RequestRender()
'		_donut.Rotate( .2,.4,.6 )
		_scene.Update()
		_camera.Render( canvas )
		canvas.DrawText( "FPS="+App.FPS,0,0 )
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

As a follow-up, FixedJoint isn't really good enough for this, as it still allows flexing (watch when it hits the ground):

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	Field _ground:Model
	'Field _donut:Model
	Field box1:Model
	Field box2:Model
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		'create ground
		Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
		Local groundMaterial:=New PbrMaterial( Color.Lime )
		_ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
		_ground.CastsShadow=False

		Local gcol:BoxCollider = _ground.AddComponent <BoxCollider> ()
		
		gcol.Box = groundBox
		
		Local gbody:RigidBody = _ground.AddComponent <RigidBody> ()
		gbody.Mass = 0
		
		
		'create donut
	'	Local donutMaterial:=New PbrMaterial( Color.Red, 0.05, 0.2 )
	'	_donut=Model.CreateTorus( 2,.5,48,24,donutMaterial )
	'	_donut.Move( 0,2.5,0 )
	
		Local geom:Boxf = New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)
		
		box1 = Model.CreateBox (geom, 2, 2, 2, New PbrMaterial (Color.Red))
		box1.Move (-1, 5, 0)
		box1.Rotate (Rnd (360), Rnd (360), Rnd (360))
		
		box2 = Model.CreateBox (geom, 2, 2, 2, New PbrMaterial (Color.Green))
		box2.Move (1, 7, 0)
		box2.Rotate (Rnd (360), Rnd (360), Rnd (360))
	
		Local col1:BoxCollider = box1.AddComponent <BoxCollider> ()
		col1.Box = geom
		
		Local col2:BoxCollider = box2.AddComponent <BoxCollider> ()
		col2.Box = geom
		
		box1.AddComponent <RigidBody> ()
		box2.AddComponent <RigidBody> ()
		
		box1.RigidBody.Mass = 100.0
		box2.RigidBody.Mass = 0.1
		
		' *** COMPOUND SHAPE ***
		
		'Local btc:bullet.btCompoundShape = New bullet.btCompoundShape ()
		
		'btc.addChildShape (Null, col1.Validate ())
		'btc.addChildShape (Null, col2.Validate ())
		
		' https://stackoverflow.com/questions/27760983/btcompoundshape-added-extra-shape
		
		' New rigidbody with own construction info?
		
		Local joint:FixedJoint = New FixedJoint (box1)
		
		joint.ConnectedBody = box2.RigidBody
		
	End
	
	Method OnRender( canvas:Canvas ) Override
		
		If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
		
		RequestRender()
'		_donut.Rotate( .2,.4,.6 )
		_scene.Update()
		_camera.Render( canvas )
		canvas.DrawText( "FPS="+App.FPS,0,0 )
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

My understanding is that a compound shape will treat them as if absolutely fixed together without any flex.

Here's the bullet author again, more about the use of hinge joints for solid connections, but this query was specifically about joints, rather than compound shapes, hence he advises the 6dof constraint here (note the first post is about the flexing in hinged joints)...

https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=4562#p17023

So it sounds like FixedJoint should really be the fixed 6dof joint. (That said, I'd swear those still flexed in Godot, though perhaps I just didn't find the right options.)

Compound shapes, though, are recommended for representing models with multiple simpler shapes -- you wouldn't want to have to create tons of joints for complex models! So it'd be nice to have them in eventually.