Bug? Mounted objects don't have collision
by Michael Vargas · in Torque X 2D · 04/23/2007 (2:41 pm) · 14 replies
I've moved this post to the feedback forum because I'd like to make it known if it's a bug:
I'm having a heck of a time getting collision to work for an object that I have mounted to another object. As far as I can tell, the mounter and mountee are virtually identical except that the object to mount onto the mountee is cloned from a template.
Is there some inherent restriction on collision of mounts, or am I missing something? I've rendered all the collision bounds and they all look fine, and the "spaceship" object collides just fine with "building" objects, but the turret object just passes through. I even set the object type of the turret to be identical to the player's object type and still no collision occurs. Is there something obvious I'm missing?
Needless to say, I'm looking forward to having access to the engine source. :)
Thanks,
Mike
Edit: In case it helps, I've reproduced this issue with a very simple project that I can provide if needed.
I'm having a heck of a time getting collision to work for an object that I have mounted to another object. As far as I can tell, the mounter and mountee are virtually identical except that the object to mount onto the mountee is cloned from a template.
Is there some inherent restriction on collision of mounts, or am I missing something? I've rendered all the collision bounds and they all look fine, and the "spaceship" object collides just fine with "building" objects, but the turret object just passes through. I even set the object type of the turret to be identical to the player's object type and still no collision occurs. Is there something obvious I'm missing?
Needless to say, I'm looking forward to having access to the engine source. :)
Thanks,
Mike
Edit: In case it helps, I've reproduced this issue with a very simple project that I can provide if needed.
#2
04/23/2007 (8:48 pm)
Do these mounted objects happen to be cloned from templates? I'm wondering if that has anything to do with it. I will package up a simple solution that reproduces this behavior and post a link in case you or anyone else cares to look. In the meantime I may post the basic steps to reproduce this issue, if that helps.
#3
04/23/2007 (9:36 pm)
Yeah, I clone objects, and mount them onto objects, or onto other clones.
#4
http://www.funcode.net/xna/TestStarterGame1.zip
(~42k)
I started from the starter game (Win32, but it doesn't work on Xbox either). I created 3 balls in TGBX from the default GGLogo material. The smaller round ball is named "player" and is of type "ball". The stretched ball is a template named "stretchBall", also of type "ball", but it serves as the "turret". The large round ball is named "bigrock" and is of type "obstacle". Both objects of type "ball" are set to collide with objects of type "obstacle", and vice versa (though I honestly don't know if it's necessary to make collisions 2-way like that.)
The BeginRun() method contains the code which clones the template, etc:
T2DSceneObject playerObject = TorqueObjectDatabase.Instance.FindObject("player");
T2DSceneObject stretchBall = TorqueObjectDatabase.Instance.CloneObject("stretchBall");
TorqueObjectDatabase.Instance.Register(stretchBall);
stretchBall.Mount(playerObject, "LinkPoint1", new Vector2(0, stretchBall.Size.Y / playerObject.Size.Y), 0, true);
And that's it. It seems that it should be working, but for some reason it's not. If you run the program, you'll notice that the object "player" collides just fine with the object "bigrock", but the "stretchBall" ignores collisions.
Edit: I'll PayPal $1 to the first person who can tell me what the issue is. ;)
04/23/2007 (10:24 pm)
Okay, I have a very small download at:http://www.funcode.net/xna/TestStarterGame1.zip
(~42k)
I started from the starter game (Win32, but it doesn't work on Xbox either). I created 3 balls in TGBX from the default GGLogo material. The smaller round ball is named "player" and is of type "ball". The stretched ball is a template named "stretchBall", also of type "ball", but it serves as the "turret". The large round ball is named "bigrock" and is of type "obstacle". Both objects of type "ball" are set to collide with objects of type "obstacle", and vice versa (though I honestly don't know if it's necessary to make collisions 2-way like that.)
The BeginRun() method contains the code which clones the template, etc:
T2DSceneObject playerObject = TorqueObjectDatabase.Instance.FindObject
T2DSceneObject stretchBall = TorqueObjectDatabase.Instance.CloneObject
TorqueObjectDatabase.Instance.Register(stretchBall);
stretchBall.Mount(playerObject, "LinkPoint1", new Vector2(0, stretchBall.Size.Y / playerObject.Size.Y), 0, true);
And that's it. It seems that it should be working, but for some reason it's not. If you run the program, you'll notice that the object "player" collides just fine with the object "bigrock", but the "stretchBall" ignores collisions.
Edit: I'll PayPal $1 to the first person who can tell me what the issue is. ;)
#5
04/24/2007 (9:30 am)
This is an area where TX differs from TGB. Because of the way mounted objects update, they don't check collisions. This is normally what you want since they tend to be sub-components of the parent object. If you want the mounted object's collision image considered when the parent moves, you should add the collision image to the parents collision component (and remove it when you unmount).
#6
04/24/2007 (11:42 am)
Okay Clark, I will try to do this and see how it works. I'm a little concerned because I'd like "turret" collisions to be handled differently from "spaceship" collisions, but for what I'm doing, I'm beginning to think that mounting might not even be necessary. Anyway, thanks for the help and I owe you a buck. ;) Maybe buying TorqueX pro will be sufficient. :)
#7
04/24/2007 (1:09 pm)
@Michael- let me know how it works out. Since mounted objects don't move on their own (they just inherit position from parent) I never really had a good way to make mounted objects collide. What TGB does is it moves them using their velocity and THEN inherits position from the parent (so the collisions you get are false collisions, but are close enough). This is certainly logic we can work on, though, so I'll be interested to know how this works out for you.
#8
04/24/2007 (7:14 pm)
I noticed that if you give your obsticle process collisions at rest, you can get some collision behavior... is that what you are talking about?
#9
Since I don't think your solution would give exactly the behavior I was looking for, I instead decided to try to ditch the Mount altogether and instead just "ghetto-mount" the turret by setting its position to be that of the link point's on each update. This didn't have any positive effect on collisions until I enabled "Process Collisions at Rest" on the turret, similar to what Modern1 mentioned. Even then, I didn't see any collision response, but I could see the red collision lines rendered whenever the turret overlapped an obstacle.
I also reproduced that same behavior if I set the velocity of the turret to match that of the would-be mountee with every update, after updating the position.
I'm starting to think/realize that manually setting an object's position (or even velocity) in each UpdateAnimation call is a sure-fire way to guarantee that your object won't play nice with the collision system. Am I right?
04/24/2007 (9:57 pm)
Hi Clark,Since I don't think your solution would give exactly the behavior I was looking for, I instead decided to try to ditch the Mount altogether and instead just "ghetto-mount" the turret by setting its position to be that of the link point's on each update. This didn't have any positive effect on collisions until I enabled "Process Collisions at Rest" on the turret, similar to what Modern1 mentioned. Even then, I didn't see any collision response, but I could see the red collision lines rendered whenever the turret overlapped an obstacle.
I also reproduced that same behavior if I set the velocity of the turret to match that of the would-be mountee with every update, after updating the position.
I'm starting to think/realize that manually setting an object's position (or even velocity) in each UpdateAnimation call is a sure-fire way to guarantee that your object won't play nice with the collision system. Am I right?
#10
edit:
two options I just thought of for you michael...
1: mess around with the microbes tutorial, you might find another method of creating the collision type behavior you want.
2: check out spaceshooter, in it you can find the Vector2.Distance method for getting the distance between two objects.
If you are trying to do something custom, those resources might help you get on the right course with plotting collisions.
04/24/2007 (10:39 pm)
Sorry for the quick reply last time Michael, I know I mentioned I had got mounted collisions to work. I'm not sure if I was misreading my data before(not likely) but I reloaded my own personal scenario, and I'm not getting mounted collisions either as I had described. edit:
two options I just thought of for you michael...
1: mess around with the microbes tutorial, you might find another method of creating the collision type behavior you want.
2: check out spaceshooter, in it you can find the Vector2.Distance method for getting the distance between two objects.
If you are trying to do something custom, those resources might help you get on the right course with plotting collisions.
#11
Pretty much by definition. If you think about it from a "theory" level, a collision occurs based on movement through contiguous space-time coordinates, but using a direct setPosition is a "teleportation" from a space-time location to another space-time location, without iterating over the intermediate locations directly.
That's a "pie in the sky" explanation of what Clark was talking about...when an object is mounted to another object, it only uses the parent object's physics, since that is the only object that is actually "moving".
I can understand the issue myself from a game point of view, and would have to think quite a bit more about how I might solve it given the current infrastructure.
04/24/2007 (11:06 pm)
Quote:
I'm starting to think/realize that manually setting an object's position (or even velocity) in each UpdateAnimation call is a sure-fire way to guarantee that your object won't play nice with the collision system. Am I right?
Pretty much by definition. If you think about it from a "theory" level, a collision occurs based on movement through contiguous space-time coordinates, but using a direct setPosition is a "teleportation" from a space-time location to another space-time location, without iterating over the intermediate locations directly.
That's a "pie in the sky" explanation of what Clark was talking about...when an object is mounted to another object, it only uses the parent object's physics, since that is the only object that is actually "moving".
I can understand the issue myself from a game point of view, and would have to think quite a bit more about how I might solve it given the current infrastructure.
#12
I do have a somewhat non-standard scenario, perhaps. In my game, the player is a flying saucer and the object to be mounted is a "destructo-beam" which fires straight down (think of the movie Independence Day). The two main things I need from this destructo beam are:
1) I want it to move with the flying saucer
2) I want to reap the benefits of the OnCollision event, so that I'll know not just when the destructo-beam hit an object, but also *where* contact was made (for contact location-specific particle effects, etc.)
I originally thought that by simply using the Mount() functionality, I'd get both of these for free, but I've found that's not the case. The good news is that it seems to be pretty easy to work around; I already have a solution that seems to work well (the one I described in my last post using the Process Collisions at Rest setting).
Thanks again, both of you!
04/24/2007 (11:26 pm)
I appreciate the responses, Modern1 and Stephen.I do have a somewhat non-standard scenario, perhaps. In my game, the player is a flying saucer and the object to be mounted is a "destructo-beam" which fires straight down (think of the movie Independence Day). The two main things I need from this destructo beam are:
1) I want it to move with the flying saucer
2) I want to reap the benefits of the OnCollision event, so that I'll know not just when the destructo-beam hit an object, but also *where* contact was made (for contact location-specific particle effects, etc.)
I originally thought that by simply using the Mount() functionality, I'd get both of these for free, but I've found that's not the case. The good news is that it seems to be pretty easy to work around; I already have a solution that seems to work well (the one I described in my last post using the Process Collisions at Rest setting).
Thanks again, both of you!
#13
Do a container search (I can't remember the specifics off the top of my head--it's late! But the microbes tutorial uses it in the RepellerComponent.cs iirc) at the mount point in world space coords with a small radius, and see if it picks up anything in the search. Almost by definition, they would be underneath the beam in that case. It may be called findObjects, but it's in the section where the component is finding what objects are within the radius of this component to register a push on.
I may be mixing engines here, but I know that TGB has a pickPoint() functionality on the scenegraph--Torque X may as well (which is basically exactly what the option above does, but for a radius instead of a point).
04/24/2007 (11:52 pm)
Well, given that particular circumstance, you have some options:Do a container search (I can't remember the specifics off the top of my head--it's late! But the microbes tutorial uses it in the RepellerComponent.cs iirc) at the mount point in world space coords with a small radius, and see if it picks up anything in the search. Almost by definition, they would be underneath the beam in that case. It may be called findObjects, but it's in the section where the component is finding what objects are within the radius of this component to register a push on.
I may be mixing engines here, but I know that TGB has a pickPoint() functionality on the scenegraph--Torque X may as well (which is basically exactly what the option above does, but for a radius instead of a point).
#14
One would be to modify the engine code to work like in TGB. I described above why we chose not to do this, but if you had the pro license and wanted to go this way it would work ok.
Another option is the one you implemented (simply snap to link point position every tick). The down side of that approach is that collision resolution will be on the mounted object and thus won't affect the parent as it should. You could hack around to get slightly better behavior by setting the velocity correctly on each time step ( i.e., something like (pos1-pos0)/timeStep). But that still wouldn't give the collision resolution on the correct object. Regardless, for you situation, you'll get the collisions if you just snap to link point position every tick.
The best approach, if you actually wanted collision responses, would be to mount a collision image on the parent corresponding to the mounted object. That way you get accurate collisions and they show up on the parent, where they belong. In the future we may fix things to work this way automatically, but we simply didn't have the resources to do this for 1.0.
04/25/2007 (10:29 am)
@Michael, for your case I think there are a lot of work arounds. One would be to modify the engine code to work like in TGB. I described above why we chose not to do this, but if you had the pro license and wanted to go this way it would work ok.
Another option is the one you implemented (simply snap to link point position every tick). The down side of that approach is that collision resolution will be on the mounted object and thus won't affect the parent as it should. You could hack around to get slightly better behavior by setting the velocity correctly on each time step ( i.e., something like (pos1-pos0)/timeStep). But that still wouldn't give the collision resolution on the correct object. Regardless, for you situation, you'll get the collisions if you just snap to link point position every tick.
The best approach, if you actually wanted collision responses, would be to mount a collision image on the parent corresponding to the mounted object. That way you get accurate collisions and they show up on the parent, where they belong. In the future we may fix things to work this way automatically, but we simply didn't have the resources to do this for 1.0.
Torque 3D Owner Will O-Reagan
Modern Intrigues
edit: I thought about it, and I'm sure I have created collisions with mounted objects, I have many, about 400 in my scene. Why don't you post your idea and maybe I or someone else can take a look at it.