Game Development Community

Door resources in the works.. but need help.

by Steve Kilcollins · in Torque Game Engine · 07/10/2006 (8:43 pm) · 24 replies

I needed doors (mainly sliding doors) for what I'm doing so I've created a sliding door object (c++ code) which will slide the door in 14 different directions. (Up, down, left, right, forward, backward, (and the diagonal directions) left up, left down, right up, right down, forward up, forward down, backward up and backward down). The door will move in the direction specified for a number of units in a certain number of ticks. Will also close either manually or by a Holdopen timer. Collisions move, no special modelling tricks, interpolated and network ready.


My problem:
I'm trying to create a rotating door C++ object. I got it to rotate but it was rotating at the center of the object. So I added a hingeNode. I got the hingeNode to rotate by using the animate() function. But I discovered that the collision, and bounding box doesn't move.

What I want to do it rotate around the hingeNode. But I'm not sure which transform to use and just how to do it.

The RotatingDoorShape is derived from Shapebase

Here's what I have for the animate() function
RotatingDoorShape::onNewDatablock()
{
    ....
	hingeNode = getDataBlock()->hingeNode;
	mShapeInstance->setNodeAnimationState(hingeNode,TSShapeInstance::MaskNodeHandsOff);
}

RotatingDoorShape::openDoor()
{
      ...

	hingeMat = &mShapeInstance->mNodeTransforms[hingeNode];
	hingePos = getDataBlock()->shape->defaultTranslations[hingeNode];
	m_velocity = mDegToRad((F32)m_maxOpenAngle) / ((F32)m_dooropentimer / (F32)TickMs);

     ...
}

RotatingDoorShape::processTick
{

               	   currentRotation += (m_velocity * (F32(TickMs) / 1000.0f));
	   hingeMat->set(EulerF(0,0,currentRotation),hingePos);

	   mShapeInstance->setDirty(TSShapeInstance::TransformDirty);
	   mShapeInstance->animate();


}
Now getting rid of the animate() and trying to actually rotate the door, here's what I have so far..

RotatingDoorShape::openDoor()
{
      ...

	hingeMat = &mShapeInstance->mNodeTransforms[hingeNode];
	m_velocity = mDegToRad((F32)m_maxOpenAngle) / ((F32)m_dooropentimer / (F32)TickMs);

     ...
}


RotatingDoorShape::processTick
{

               	   currentRotation = (m_velocity * (F32(TickMs) / 1000.0f));
	   hingeMat->set(EulerF(0,0,currentRotation));

	   m_originalPosition = mObjToWorld;


 <    here's where I need the help,  what do I do next?  >

}

I've been struggling with this for a week and as soon as i can get this solved, then I can release both the sliding and rotating doors as a resource.
Page «Previous 1 2
#1
07/11/2006 (2:39 pm)
I'm tracing down the load of the shape and found (and watched) where the different nodes get transformed from one to the other. I just need to find where the transfrom from local space to world space takes place and where the collision box and bounding box get transformed.

I think what I'm going to probably the same sort of the thing.. transform each node up from my hingenode through to the bounding box. I think I'm close to figuring it out. Course, there probably is an easier way...but it is a good learning experience.
#2
07/11/2006 (2:44 pm)
I'm very interested in this. I'm working on a rotating door, but it involves putting the door's pivot point along its side axis, and rotating it by setting its rotation transform.

Although the collision box will rotate with the object, it won't perform any collision detection while it's rotating. However, I'm looking into ways around this.
#3
07/13/2006 (10:24 pm)
Just a little update:

I almost have it. I have the 2 boxes moving with the door when you open the world editor and select the door. the yellow box resizes (which I would expect the bounding box to resize) but the red/blue box also resized instead of just rotating.

The whole thing is rotating around my "hinge" node. Collision is moving/rotating too but is still a little screwed up. When it rotates a little bit, the collision box doesn't work quite correctly. Will work fine one way, but when you try to go the other way.. the collision box isn't quite where it should be.

The way I'm doing it currently, may not be the way it should be done; but I'm still experimenting and learning. There is another way I'm thinking of doing it, so I'll have to try and experiement with it.
#4
07/13/2006 (10:37 pm)
Actually, I've just figured it out on my end.

I have a rotating door working in my game along with effective collision, although collision detection is not 100% perfect. I'm using the door's world box for collision rather than the collision mesh of the door, so it may not react precisely to collision, but it's darn near close. Close enough for my purpose, for certain.

The way I have it set up is that the door will open along a 90 degree angle by rotating its Z axis (with setTransform). If the player gets in the way of the door's motion, it will pause until the player gets out of the way. It will even detect collision if the player is in the way but not moving. And, it's all done in script, too, so no engine modification needed.

The only real issue occurs with doors that open by swinging away from the player. If the player tries to pass through the door before it is fully open, collision detection will trigger a collision and the door will pause, thinking the player is in the way (even though he really isn't, since the door is swinging open away from the player). There are some things I can try which might overcome this, though.
#5
07/14/2006 (1:24 am)
Like checking the collision angle, or the direction the door and the player are facing ( only do pause if the door and player are facing opposite directions).
#6
07/14/2006 (6:37 am)
I was using the animateNodes() function to do the transform from my hinge node all the way up through, then rebuilding the bounds and mObjBox.

My plan is to use a hinge node that is parent to the whole door mesh (including collision meshes) so you could rotate it along any axis. Which then you could have a garage door (the open upand out ones), drawbridge, etc. and not just be restricted to just the Z

I was just going to make sure collision worked. I wasn't going to do any push-player or pause door, etc, as they could do that in script.


Rubes, how did you get/move the pivot point?
#7
07/14/2006 (8:10 am)
@Steve: I just had our modeler create a door DTS with a pivot point at the side edge, so when you alter the Z rotation using setTransform the door will rotate from the pivot point rather than the center of the world box.

That also rotates the door's collision mesh, but collision checking, for the most part, is based on the player colliding with an object, not the other way around. There are some objects that do their own collision checking (projectiles and rigidShapes come to mind), but rather than trying to adapt those I just tried my own quickie script-based collision check using the door's world box.

I'll post the details in a thread or resource in a little bit.

@Dave: Problem is, the door is always facing the same way, whether it's opening or closing, and I don't think the angle will tell you much because the player could be in front of, or behind, the door as it is opening or closing. What would really help is to know where the door was vs. where the door is. So perhaps checking the distance between the player and the door before its next rotation step and immediately after might help.
#8
07/14/2006 (8:45 am)
That's odd.. maybe I didn't do something correct. I had moved the origin in max to the outer edge of the door and when I tried to rotate it, it still rotated from the center.

I'll have to play with that again, in max
#9
07/14/2006 (8:50 am)
How are you rotating it?

If I try to rotate my door in the world editor by using the ALT-click-drag method, it will still rotate from the center. But if you just manually change the Z rotation number, it will rotate the way it's supposed to.

Our modeler also told me that he adjusted the pivot point of the door mesh, the collision mesh, and the bounds box. He's not sure if you need to do all three, but maybe that's necessary after all.
#10
07/14/2006 (9:55 am)
What I was doing before putting in the hinge node was
oldRotation = mCurrRotation
newRotation = oldRotation + (m_velocity * (F32(TicksMS) / 1000.f)

mCurrDeltaBase = newrotation;
mCurrBackDelta = mCurrRotation - newPosition;
mCurrRotation = newRotation;

AngAxisF aa;
aa.axis.x = 0;
aa.axis.y = 0;
aa.angle = newRotation;

matrixF mat;
aa.setMatrix(&mat);
setTransform(mat);


I've changed the code so many times,,I had position in there as well. I don't know if that is correct now or not.. as what I was doing before.

It would rotate.. but the position was way off.. when it started to rotate,, it took off into the sky still rotating (and correctly),, but it was rotating correctly. Just taking off like a bat-outta-hell.

I'll have to play in max..and play again with changing the pivot/origin.

using the "hinge" node... just doesn't feel right. Seems like it should work with the changing of the pivot/origin.
#11
07/22/2006 (9:34 pm)
Just wanted to say... I figured it out. I got the object to rotate around the "hingeNode". I was ready to give up. then for some reason I saw the worldeditor class and said,, hmmmm how does the editor rotate.

And sure enough it did what I wanted. When you rotate an object in the editor, you actual rotate it using the gizmo (if you don't type it in). Since the gizmo end points are not in the center,, the class creates an offset -- the difference between the center of the object and the point of the mouse. that clued me in.

Collision boxes and world boxes move as they should.

In a couple of weeks, I should be able to put a resource out that adds sliding doors and rotating doors to the engine.
#13
07/23/2006 (11:18 am)
Oh, sure... ya wait until AFTER he's done all the legwork to point it out. heheheheh
#14
07/23/2006 (11:19 am)
Thus a lesson has been learned. . . use the SEARCH button =)
#15
07/23/2006 (11:23 am)
True, but I've been doing the same thing...my door method is different than the method in that resource, but later I learned I was doing the same thing that someone else said they had already accomplished in the comments section...
#16
07/23/2006 (7:21 pm)
Actually.. this is different. Its pure engine code. I tried the scripted doors from Advanced 3d Game Programming All In One and it was too jerky, which gave me the idea to do it in the engine so the movement would be interpolated. The one posted above is animated in a modelling program. Mine, you just put a hinge node were you want it to rotate then put the collision box and mesh a child of the hingenode and your done.

In script on serverside, to open my door you just use .open(); or .close(); and it takes care of eveything.. moving the collision boxes, etc. All you would need is a check if the collision occurs against any other object.. move that object back like a unit of some number. so you could actually push the player forward or backward.. in a room or out of the room.

My sliding door, as stated above, will move in different directions and doesn't need a hinge.
#17
07/23/2006 (7:21 pm)
I had done a search,, but didn't care for any of the resources that I found.

And I'm not complaigning. I've learned a lot from doing this. Learnt more on transforms, local and world space, matrix multiplication, how the meshes are put together, how the animation system works where all the transforms are stored,, etc.. etc..

I'm really glad I did this.
#18
07/23/2006 (8:13 pm)
I don't have A3DGPAIO, but I'd be interested in knowing how he says to implement the door. Could you perhaps summarize it? I'm guessing he just changes the rotation transform...which can result in a pretty jerky motion. I tried that, too, and then realized that the best way for me to go was to create an animated door, and then place an invisible collision door on top of it that I rotate by altering its rotation transform.

One thing that I have done that I haven't seen in any other door resource is to have the door make its own collision checks, so it can detect when it is colliding with the player. You mention something like this, but how did you accomplish it? Most collision checking in Torque is simply the player checking for collisions against other objects, so if the player is standing still a door can still open right through him -- since collision checking only occurs while the player is moving.

I did it by manually making a collision check in script every time I rotate the invisible collision door, using its world box and ContainerFindFirst(). If the player is in the world box, then it pauses the animation until he gets out of the way.

I agree with you, though, it was a great experience. I also learned a lot about the exact same things...plus I have my own solution.
#19
07/23/2006 (9:24 pm)
Yes... a3dgpaio did change the rotation transform.

I haven't really looked at the collision routines, since my door is built over the shapebase I just assumed an OnCollision script call would occur. I haven't really looked at any collision code--I just know the collision box moves with the rotation. I just ran a test and a collision did not get triggered.

So I'll look at doing a couple of things:
a) in processTick, do a call to new script function onDoorMovement and let the user do a castray in script..
b) look at the projectile code (and the other classes that do collision) and copy that code to my processtick and then call a script onCollision();

I'm inclined to do option b as that would be cleaner for the scripters as then they can decide what they want to do with the collision.
#20
07/23/2006 (9:38 pm)
Thanks...I actually also looked into using the projectile code for collision detection, but I recall thinking it wouldn't work because the projectile code does something like estimate where the projectile is about to be when it moves, and then draws a ray from its current position to its next position and checks to see if it intersects with anything. Or something like that. I couldn't think of an easy way to do apply that in the case of a door, so I went a different direction.
Page «Previous 1 2