Model train

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Model train

Post by raven_coda »

I'm trying model a simple train but having trouble getting the cars to follow in a line. My thought was to attacha follow spline animator to the front car then have the other follow via a milkshape joint and the hitch or link of that car. Prob is the cars just fly all over the place.
Here's the model and pick. Only one joint labeled "Link". Notice the nose of the car is at the origin.

[img]http://www.scmlaw.com\trailer.jpg[/img]
Milkshape Trailer

and here's the code

Code: Select all

#include <irrlicht.h>

using namespace irr;
using namespace scene;
using namespace core;

#pragma comment(lib, "Irrlicht.lib")

class car
{
public:
	car(scene::IAnimatedMeshSceneNode* Node, scene::ISceneNode* Link)
	{
		node=Node;
		lastpos=node->getAbsolutePosition();
		link=Link;
	}

	void update()
	{
		if (link)
			node->setPosition(link->getAbsolutePosition());
		vector3df rot=node->getAbsolutePosition()-lastpos;
		node->setRotation(rot.getHorizontalAngle());
		lastpos=node->getAbsolutePosition();
	}
	scene::IAnimatedMeshSceneNode* node;
private:
	scene::ISceneNode* link;
	vector3df lastpos;
};

void main()
{
	IrrlichtDevice* device=irr::createDevice(video::EDT_DIRECT3D9, dimension2d<s32>(320, 240));
	ISceneManager* smgr=device->getSceneManager();
	video::IVideoDriver* driver=device->getVideoDriver();
	
	array<car> train;
	train.push_back(car(smgr->addAnimatedMeshSceneNode(smgr->getMesh("../trailer.ms3d")),0));
	train.push_back(car(smgr->addAnimatedMeshSceneNode(smgr->getMesh("../trailer.ms3d")), train[train.size()-1].node->getMS3DJointNode("Link")));
	train.push_back(car(smgr->addAnimatedMeshSceneNode(smgr->getMesh("../trailer.ms3d")), train[train.size()-1].node->getMS3DJointNode("Link")));
	train.push_back(car(smgr->addAnimatedMeshSceneNode(smgr->getMesh("../trailer.ms3d")), train[train.size()-1].node->getMS3DJointNode("Link")));
	train.push_back(car(smgr->addAnimatedMeshSceneNode(smgr->getMesh("../trailer.ms3d")), train[train.size()-1].node->getMS3DJointNode("Link")));

	for (int i=0; i<train.size(); i++)
		train[i].node->setMaterialFlag(video::EMF_LIGHTING, false);

	smgr->addCubeSceneNode(1,0,-1,vector3df(0,-10,0),vector3df(0,0,0), vector3df(500,1,500));

	array<vector3df> points;
	points.push_back(vector3df(-200,0,-100));
	points.push_back(vector3df(200,100,-100));
	points.push_back(vector3df(100,50,200));
	points.push_back(vector3df(0,0,0));
	
	ISceneNodeAnimator* anim=smgr->createFollowSplineAnimator(device->getTimer()->getTime(), points, .10);
	train[0].node->addAnimator(anim);
	anim->drop();

	smgr->addCameraSceneNodeFPS();
	while (device->run())
	{
		for (int i=0; i<train.size(); i++)
			train[i].update();

		driver->beginScene(true,true, video::SColor(255,80,80,80));
		smgr->drawAll();
		driver->endScene();

	}
device->drop();
}
anybody see what I'm doing wrong or a better way to do this? Seems kind of over kill to intigrate a physics engine just for this.
Last edited by raven_coda on Wed May 23, 2007 11:00 pm, edited 1 time in total.
Definition of an Upgrade: Take old bugs out, put new ones in.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

So the problem is that the train cars are parented to the front car. When the front car moves or rotates, the children cars move and rotate with it. The entire assembly is going to rotate about the origin of the first train car.

Does the first car move like you want? I'm guessing that the position stuff is correct, but the car will not turn like you want it to. The spline animator doesn't do rotations.

Travis
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Post by raven_coda »

I thought about that. Thus, the cars are not actually children to car in head of them. They just keep a reference to the joint of the car in head of them. As for the rotation the lead car is fine and then next car is almost fine but it wabbels at bit which cause even more wabbing in the car behind it and etc. the meat to the code is in the update under the car class.
Definition of an Upgrade: Take old bugs out, put new ones in.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Ah, I misread the code. It looks like the addAnimatedMeshSceneNode() is getting the previous train as a parent, but that is the car constructor.

If you want to use getAbsolutePosition(), you probably need to call updateAbsolutePosition() after you call setPosition() If you just use getPosition() and setPosition() you should not have that problem. Since you aren't transforming coordinates, your code already assumes that the train cars are children of the root scene node and have no parent transformation, so using setPosition() and getPosition() won't be making any more assumptions than your code is already making.

Travis
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Post by raven_coda »

Thanks for the tip. I took out most the getAbsolutePosition calls (had to leave the one for the link node as it is a child of the milkshape joint) but I still have the trouble. I have found that if I call the update less frequent that the problem with them bouncing around as much greatly goes away however then they don't follow smoothly. I notice it gets much worse when the train is turning a corner.

I also tried calling updateAbsolutePosition() before to see if that cleans anything up but no luck.
Definition of an Upgrade: Take old bugs out, put new ones in.
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Post by raven_coda »

The more I work with this the more I believe this model will not work. The cars seem to be not following the same path and cut corners. Since a train follows a track then this won't work. I tried assigning a followSplineAnimator to each car but apparently the followSplineAnimator goes slower through corners so all the cars get bunched up. At this point I'd be willing to use a physics engine but I don't know of a physics engine that will allow me to restrict the movement of the objects to a curved path (the tracks).

Can anyone give me some tips on how you would model a train, or roller coaster for that matter?

Thanks.
Definition of an Upgrade: Take old bugs out, put new ones in.
Post Reply