Jump to content

Body attached to a bone (strange behavior)


Jolinah
 Share

Recommended Posts

Hi,

 

I was trying to attach a TBody (Cylinder) to a TBone of my animated player mesh (with parenting), but strange things have happened. First, when I set the mass to something bigger than 0 the body is falling, even if I set GravityMode to 0. If the mass is 0 it stays in place and moves along with the animated mesh, but in DebugPhysics mode it is flickering (changing color between green and red) and no collisions are recorded, although I have set up collisions and collision types.

 

I think it has something to do with the parenting. If I create a body which is not attached to the mesh, the collision works and I am able to set a mass bigger than 0 and GravityMode 0.

 

I am developing a soccer game and the idea was that the legs of the player can collide with the ball, so I thought the simplest thing would be to attach one or two cylinders to the legs. I am just wondering why this does not work. Is there a more preferable solution to this problem or has anyone encountered a similar problem?

 

Thanks in advance and sorry for my English.. :)

 

Michael

Link to comment
Share on other sites

Few questions before answer:

Have your character a body itself?

Is this body active? (mass > 0)

Also could you show your code to understand if there are errors?

 

Anyway i suppose all the body should collide (as for example if i shoot the ball should not pass trough his chest).

Also i suggest you to use joint to drag the ball (also it's usefull when you receive a tackle).

Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10.

Link to comment
Share on other sites

Thank you for your reply Joh :)

 

The character does not have a body itself. I create bodies in the code and attach them to the bones (maybe I will create a little editor for this). I think I'm going to attach a simple body to most of the bones, so the ball can collide with everything and I am able to tell which part of the character was hit.

 

In the mean time I found out that the problem is TMesh.Copy. I set up the bodies for the loaded mesh and was working with a copy of this mesh all the time, because it's a multiplayer game and each player instance uses a copy of the mesh. It seems that TMesh.Copy does not copy the GravityMode for the children. When I set the GravityMode of the copy to 0 it was working. Is this a bug or normal behavior?

 

But now I have another problem: I use no response collisions, but whenever a collision occurs the body (cylinder) rotates, although there is no code in the collision callback at all. The ball behaves correctly, it does not move or rotate.

 

Thank you for your tip with the joints, I will have a look at those.

 

 

I made a little test program with the same situation. Here are some screenshots:

 

http://zehr.de/screenshots/screenshot1.png

http://zehr.de/screenshots/screenshot2.png

http://zehr.de/screenshots/screenshot3.png

 

Here is the source code and the mesh which was used:

 

http://zehr.de/downloads/collision_test.zip

 

SuperStrict

Framework leadwerks.engine

GCSetMode(2)
RegisterAbstractPath("")

'Collision types
Const COL_PLAYER:Int = 1
Const COL_WORLD:Int = 2
Const COL_BALL:Int = 3

'Initialize graphics and world
Graphics(800, 600, 0, 0)

Local world:TWorld = CreateWorld()
Local gbuffer:TBuffer = CreateBuffer(800, 600, BUFFER_COLOR | BUFFER_NORMAL | BUFFER_DEPTH)

'Create a camera
Local cam:TCamera = CreateCamera()
cam.SetPosition([0.0, 5.0, -10.0])
cam.SetRotation([10.0, 0.0, 0.0])
CameraClearColor(cam, Vec4(0.5, 0.5, 0.5, 1.0))

'Load the mesh
Local mesh:TMesh = LoadMesh("abstract::dummy.gmf")
mesh.SetPosition([- 0.5, 0.0, 10.0])

'Find the left lower leg bone of the mesh
Local lower_leg_l:TBone = TBone(mesh.FindChild("LowerLeg_L"))

'Create a body (for leg to ball collision)
Local body:TBody = CreateBodyCylinder(0.5, 2, lower_leg_l)
body.SetCollisionType(COL_PLAYER)
body.SetGravityMode(0)
body.SetMass(1)
body.SetRotation([90.0, 90.0, 0.0])
body.Move([0.0, -1.0, 0.0], 1)
body.SetCallback(OnCollision, ENTITYCALLBACK_COLLISION)

'Copy the whole mesh + body
Local mesh_copy:TMesh = mesh.Copy()
mesh_copy.SetPosition([3.0, 0.0, 10.0])

'---- Set GravityMode again on the copy... (bug?) ------------------
Local leg:TBone = TBone(mesh_copy.FindChild("LowerLeg_L"))
TBody(leg.GetChild(2)).SetGravityMode(0)
'-------------------------------------------------------------------

'Create a ground body
Local ground:TBody = CreateBodyBox(100, 0.5, 100)
ground.SetCollisionType(COL_WORLD)
ground.SetPosition([0.0, -0.5, 10.0])

'Create a ball (sphere)
Local ball:TBody = CreateBodySphere(0.5)
ball.SetCollisionType(COL_BALL)
ball.SetPosition([0.0, 2.0, 0.0])
ball.SetMass(1)

'Let the ball collide with the ground (works fine)
Collisions(COL_BALL, COL_WORLD, 1)

'Let the player collide with the ball
Collisions(COL_PLAYER, COL_BALL, 2)


'Animation frame used to animate both meshes
Local animFrame:Float = 0


'Use wireframe and debug physics
AmbientLight([0.8, 0.8, 0.8])
WireFrame(1)
DebugPhysics(1)

HideMouse()
MoveMouse(400, 300)

Repeat
UpdateAppTime()

'Use W, S, A and D to move the camera
If KeyDown(KEY_W) Then
	cam.Move([0.0, 0.0, 0.1])
ElseIf KeyDown(KEY_S) Then
	cam.Move([0.0, 0.0, -0.1])
End If

If KeyDown(KEY_A) Then
	cam.Move([- 0.1, 0.0, 0.0])
ElseIf KeyDown(KEY_D) Then
	cam.Move([0.1, 0.0, 0.0])
End If

'Use left and right arrows to animate and move both meshes
If KeyDown(KEY_LEFT) Then
	animFrame:-AppSpeed()
	If animFrame < 0 Then
		animFrame = 148 + animFrame
	End If
	animFrame = animFrame Mod 148
	mesh.Move([0.0, 0.0, 0.1])
	mesh_copy.Move([0.0, 0.0, 0.1])
ElseIf KeyDown(KEY_RIGHT) Then
	animFrame:+AppSpeed()
	animFrame = animFrame Mod 148
	mesh.Move([0.0, 0.0, -0.1])
	mesh_copy.Move([0.0, 0.0, -0.1])
End If

'Animate both meshes with the current frame
mesh.Animate(animFrame)
mesh_copy.Animate(animFrame)

'Rotate the camera acording to the mouse movement
Local mx:Float = MouseX() - 400
Local my:Float = MouseY() - 300
MoveMouse(400, 300)

Local rot:TVec3 = Vec3(cam.rotation.x + my / 5.0, cam.rotation.y - mx / 5.0, cam.rotation.z)
cam.SetRotation(rot)


UpdateWorld(AppSpeed())

SetBuffer(gbuffer)
RenderWorld()

SetBuffer(BackBuffer())
RenderLights(gbuffer)

Flip 1
Until KeyHit(KEY_ESCAPE)

ClearWorld()
EndGraphics()

GCCollect()
End


'Collision callback
Function OnCollision(e1:TEntity, e2:TEntity, pos:TVec3, normal:TVec3, force:TVec3, speed:Float)
DebugLog("Collision")
End Function

 

Thanks

Link to comment
Share on other sites

But now I have another problem: I use no response collisions, but whenever a collision occurs the body (cylinder) rotates, although there is no code in the collision callback at all. The ball behaves correctly, it does not move or rotate.

Of course this is quite normal, your body collide with the ball (right?) it have 0 gravity so every hit it receive it will made a spin or rotation. You could solve this problem in 2 way:

Set the collision mode to 0 (no collision performed) so you know when the leg hit the ball and in wich point but you should choice where the ball should go (with math calculation) in this case you could also "cheat" (as PES do damn game!)

Or force the cylinder to don't spin setting his torque/omega every loop.

Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10.

Link to comment
Share on other sites

That sounds logically to me, but I thought the "no response collision, mode 2" does not respond in any way? At least the tutorial sais with mode 2 it is only recording the collisions, but it is not doing anything (except calling the collision callback).

 

This is exactly what I was trying to do. With collision mode 0, do you mean something like this?

 

Collisions(COL_PLAYER, COL_BALL, 0)

 

With this code, the cylinder isn't rotating any more, but no collision is recorded either.

 

I will try the second option now. Thank you for your help :)

Link to comment
Share on other sites

mmm Collisions(COL_PLAYER, COL_BALL, 2) this should work.. But i see you already did.

This is strange.

 

Just for curiosity insert this also Collisions(COL_BALL,COL_PLAYER, 2)

Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10.

Link to comment
Share on other sites

I tested:

 

Collisions(COL_PLAYER, COL_BALL, 2)

 

Collisions(COL_BALL, COL_PLAYER, 2)

 

Collisions(COL_PLAYER, COL_BALL, 2)
Collisions(COL_BALL, COL_PLAYER, 2)

 

There is no difference (except the callback is eventually called twice). I have written a bug report, in the mean time I will try to find a work around.

 

 

Edit:

 

I found a work around:

Function OnCollision(e1:TEntity, e2:TEntity, pos:TVec3, normal:TVec3, force:TVec3, speed:Float)
TBody(e1).SetRotation([90.0, 90.0, 0.0])
End Function

 

This sets the rotation back to its initial value (works).

Link to comment
Share on other sites

  • 2 weeks later...

Ok, according to Josh this is not a bug:

 

"A physics body cannot have a parent. The parent matrix will override the body's simulation and cause it to not work."

 

So, is there a way to check whether two meshes are intersecting with each other (without models/bodies)? I don't need physics simulation in this case. I've already tried line picks from the ball to the player (only when the ball is near to the player, at an interval of 50ms). It works, but it's a little bit slow.

Link to comment
Share on other sites

Well there are a plenty of ways, but you need one working on your game.

Do you use controller for player? I imagine the ball won't collide to that controller right?

Well you can do it "collide" but no collision apply, so whenever it's collided transform that player in local space to the ball so now you know where the player is (if it's behind you should skip it) after that you could use the linepick from the ball in the his z direction (better should be a spheric to plane collision but if doing wrong it will slow) long as the radius of the controller if hit the player you know where, you could in that case find the bone.

I hope this could help you.

Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...