Jolinah Posted May 4, 2010 Share Posted May 4, 2010 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 Quote Link to comment Share on other sites More sharing options...
Joh Posted May 5, 2010 Share Posted May 5, 2010 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). Quote Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10. Link to comment Share on other sites More sharing options...
Jolinah Posted May 5, 2010 Author Share Posted May 5, 2010 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 Quote Link to comment Share on other sites More sharing options...
Joh Posted May 5, 2010 Share Posted May 5, 2010 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. Quote Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10. Link to comment Share on other sites More sharing options...
Jolinah Posted May 5, 2010 Author Share Posted May 5, 2010 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 Quote Link to comment Share on other sites More sharing options...
Joh Posted May 5, 2010 Share Posted May 5, 2010 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) Quote Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10. Link to comment Share on other sites More sharing options...
Jolinah Posted May 5, 2010 Author Share Posted May 5, 2010 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). Quote Link to comment Share on other sites More sharing options...
Jolinah Posted May 17, 2010 Author Share Posted May 17, 2010 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. Quote Link to comment Share on other sites More sharing options...
Joh Posted May 17, 2010 Share Posted May 17, 2010 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. Quote Intel Corei7-6700, NVIDIA GeForce GTX 980, 32GB DDR4, W-10. Link to comment Share on other sites More sharing options...
Recommended Posts
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.