And another one! Physics engine, that is!

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

Monster's newton wrapper gave hangups when you tried to read the terrain vertexes that way. I think the problem is that terrain vertexes are now stored elsewhere
No. The "problem" is that you've never been able to read terrain vertices that way. The example screen shots I posted just use a mesh that looks like a bit of terrain, not an actual terrain scene manager.

For a large terrain you'd never use a full trimesh collision system since that would use a vast amount of memory if the terrain's anything like a decent size. OgreOde uses ODE's Terrain collision primitive, modified to use a callback for height data, and Ray scene queries. I've no idea whether something like that would be possible with Newton.
I don't really understand what is vertex buffer and i'm just copying yours.Btw,the error occurs in your source code too,so i guess it is my terrain mesh causing the problem
You need to look up the code that's been posted a few times on these forums for reading vertex and index data from meshes, and use it to replace my much simplified code round about where it says;

Code: Select all

(TODO: Don't assume the format of the buffers)

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

I don't really know what vertex and indices are. Which replacement do u recomend?
Game programming is fun!

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

The OgreOde trimesh sample contains more reliable code to obtain vertex and index information from meshes, as does the GroundCover class as posted in the "Rendering a LOT of things" thread.

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

Sorry to say this but i really don't know what are indices and vertices. And what are the parameters for the NewtonTreeCollisionAddFace ? I need a working sample on using trimesh collision with newton+ogre. I've failed to get ogreode running and the same goes to ogretok. Newton is my last hope :cry:
Game programming is fun!

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

You don't need to get OgreOde running, you can just reuse the trimesh sample code to feed the data to Newton. In the same way that the Newton demo does, but with the more robust vertex reading code.

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

All of the objects are passing through my trimesh after i copied the code from ogreode.Here is my code for creating the trimesh:

Code: Select all

mapEntity=mSceneMgr->createEntity("terrain","terrain.mesh");
		
		mapNode=mSceneMgr->getRootSceneNode()->createChildSceneNode();
		mapNode->attachObject(mapEntity);
		newtonMap=NewtonCreateTreeCollision(nWorld,NULL);
		NewtonTreeCollisionBeginBuild(newtonMap);
		Mesh* mesh = mapEntity->getMesh();
		size_t indices_needed = 0,vertices_needed = 0;
		bool added_shared = false;

		if(mesh)
		{
			// Calculate how many vertices and indices we're going to need
			for(int i = 0;i < mesh->getNumSubMeshes();i++)
			{
				SubMesh* submesh = mesh->getSubMesh(i);

				// We only need to add the shared vertices once
				if(submesh->useSharedVertices)
				{
					if(!added_shared)
					{
						VertexData* vertex_data = mesh->sharedVertexData;
						vertices_needed += vertex_data->vertexCount;
						added_shared = true;
					}
				}
				else
				{
					VertexData* vertex_data = submesh->vertexData;
					vertices_needed += vertex_data->vertexCount;
				}
				
				// Add the indices
				Ogre::IndexData* index_data = submesh->indexData;
				indices_needed += index_data->indexCount;
			}
		
			// Allocate space for the vertices and indices
			Vector3* vertices = new Vector3[vertices_needed];
			int* indices = new int[indices_needed];
			
			size_t current_offset = 0,shared_offset = 0,next_offset = 0,index_offset = 0;
			added_shared = false;
			Vector3 scale(0.4,0.3,0.4);
		Vector3 pos(0,3,0);
			// Run through the submeshes again, adding the data into the arrays
			for(int i = 0;i < mesh->getNumSubMeshes();i++)
			{
				SubMesh* submesh = mesh->getSubMesh(i);

				Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
				if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
				{
					if(submesh->useSharedVertices)
					{
						added_shared = true;
						shared_offset = current_offset;
					}

					const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
					Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
					unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
					Ogre::Real* pReal;

					for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
					{
						posElem->baseVertexPointerToElement(vertex, &pReal);

						vertices[current_offset + j].x = ((*pReal++) * scale.x) + pos.x;
						vertices[current_offset + j].y = ((*pReal++) * scale.y) + pos.y;
						vertices[current_offset + j].z = ((*pReal++) * scale.z) + pos.z;
					}
					vbuf->unlock();
					next_offset += vertex_data->vertexCount;
				}

				Ogre::IndexData* index_data = submesh->indexData;

				size_t numTris = index_data->indexCount / 3;
				unsigned short* pShort;
				unsigned int* pInt;
				Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
				bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
				if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
				else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

				for(size_t k = 0; k < numTris; ++k)
				{
					size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;
					
					unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
					indices[index_offset + 0] = vindex + offset;
					vindex = use32bitindexes? *pInt++ : *pShort++;
					indices[index_offset + 1] = vindex + offset;
					vindex = use32bitindexes? *pInt++ : *pShort++;
					indices[index_offset + 2] = vindex + offset;

					index_offset += 3;
					NewtonTreeCollisionAddFace(newtonMap,3,(float*)indices,sizeof(indices),0);
				}
				ibuf->unlock();
				current_offset = next_offset;
			}

			delete[] vertices;
			delete[] indices;
		}

		NewtonTreeCollisionEndBuild(newtonMap,true);
I just add the NewtonTreeCollisionAddFace(newtonMap,3,(float*)indices,sizeof(indices),0);
and remove the trimesh for ode.Am i doing it right?
Game programming is fun!

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

When you're calling NewtonTreeCollisionAddFace you're passing the indices, when you should be adding the actual vertices.
Your "for(size_t k = 0; k < numTris; ++k)" loop should be something like;

Code: Select all

for(size_t k = 0; k < numTris; ++k)
{
    size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;

    unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
    int i0 = vindex + offset;
    vindex = use32bitindexes? *pInt++ : *pShort++;
    int i1 = vindex + offset;
    vindex = use32bitindexes? *pInt++ : *pShort++;
    int i2 = vindex + offset;

    index_offset += 3;

    float verts[3][3];

    verts[0][0] = vertices[i0].x;
    verts[0][1] = vertices[i0].y;
    verts[0][2] = vertices[i0].z;

    verts[1][0] = vertices[i1].x;
    verts[1][1] = vertices[i1].y;
    verts[1][2] = vertices[i1].z;

    verts[2][0] = vertices[i2].x;
    verts[2][1] = vertices[i2].y;
    verts[2][2] = vertices[i1].z;
               
    NewtonTreeCollisionAddFace(newtonMap,3,verts[0],sizeof(verts[0]),0);
}
Something like that, but note that I haven't compiled or tested this code!
;)

Also, you don't need to store the list of indices since you're calculating them, dereferencing the vertices using them, and passing the resultant triangle directly to Newton. But that's a minor point and won't actually affect the way the code works.

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

Thanks for the reply but my objects are still passing through the terrain. Is there any other better physics engine that can be used with ogre easily? ogretok style ode wraper for axiom is pretty good with the stability and easy to use.I hope there is one for ogre too.


OgreOde&OgreTok-> Can't even compile it with cvs version of ogre.Errors keep coming up :cry:
Game programming is fun!

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

Thanks for the reply but my objects are still passing through the terrain.
Then you'll need to debug your code and work out what's going wrong. Check the call to NewtonTreeCollisionAddFace to make sure the correct vertices are being added. Simplify your code so that you build up a very simple trimesh, e.g. manually create a plane with just two triangles in it, rather than trying to read from the mesh. Then, once that's working, check the mesh reading code.
OgreOde&OgreTok-> Can't even compile it with cvs version of ogre.Errors keep coming up
I don't know about OgreTok, but OgreOde works with Ogre 0.14.0 and possibly 0.14.1, not the CVS version. I'm currently working to get OgreOde updated to the CVS version of Ogre and added to ogreaddons, but that's at least a couple of weeks away.

Is there a reason why you need to use the CVS version of Ogre?
Is there any other better physics engine that can be used with ogre easily?
You've currently got the options of ODE (either OgreOde or the ReferenceAppLayer, or even through the Yake framework), Newton, Tokamak and Novodex. How many more choices would you like?

As for "easily"; start simply and work your way up.

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

Is there a reason why you need to use the CVS version of Ogre?
Perhaps i should stick with 0.14.1 :P
You've currently got the options of ODE (either OgreOde or the ReferenceAppLayer, or even through the Yake framework), Newton, Tokamak and Novodex. How many more choices would you like?
Oh well,since you have made a great game with ogreode engine,i think it is time for me to go back to the ogreode world :D
Game programming is fun!

Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

Monster, would you please post ALL the MESH files you used in the Newton demo program?

Or email it to me. Some of us don't have access to drawing programs (or like me, can't draw for shit).

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

Modelers like Wings3D and Blender are free AFAIK, so you might try using one of those.

The Ball and Box models are just, well, a ball and a box, no great artistic talent needed. The robot comes with Ogre, but I don't think the (now ancient) demo code uses it anyway. The "terrain" mesh was created by importing a heightfield into my modeler, it's included in the OgreOde download if you must use it.

But why do you need the exact same models that I've used? The point is that it's just a demo, you can use WHATEVER MESHES YOU LIKE.

Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

Thanks.

I

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

I notice the new version of Newton (1.30) is now out.
http://newtondynamics.com/index.html

I've not had a chance to check out the SDK fully, but the precompiled demos look really cool. The variety of collision primitives on offer is particularly impressive, as is the funny tank thing in the vehicle demo! There are also some enhancements to the Ragdoll functionality, a special Character joint (e.g. for FPS style control) and a Heightfield collision primitive.

Maybe it's time to revisit my "Ogrewton" interface?

User avatar
walaber
OGRE Expert User
OGRE Expert User
Posts: 829
Joined: Sat Oct 02, 2004 2:20 pm
Location: California, USA
Contact:

Post by walaber »

indeed, 1.30 is a _vast_ improvement over the previous versions...

the most obvious improvement is the Vehicle system, which makes wheeled vehicles simple and powerful.

other additions include many more primitives:
* Cylinder * Cone * Capsule * Elipsoids * Chamfer Cylinder * ConvexHulls

...plus there is a new addition that allows you to apply an arbitrary deformation matrix (scale / skew / distortion) to any of the above primitives to further modify it's shape... for example you can skew a box to make it slanted, etc... you can even animate the shape in realtime by animating the deformation matrix.

other new features include improvements to the Ragdoll joint, and lots of other fun features :D

I hope to start working on a Ogre + Newton 1.30 project in the near future, featuring the vehicle joint prominently :D
Go Go Gadget OGRE!!
Image

chooikw
Kobold
Posts: 32
Joined: Mon Jun 28, 2004 3:58 pm
Contact:

Post by chooikw »

walaber wrote: I hope to start working on a Ogre + Newton 1.30 project in the near future, featuring the vehicle joint prominently :D
Me too! :D
Game programming is fun!

Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

I am running Ogre 0.15 and Newton 1.30.

I am having an issue with Ogre and Newton..

Ogre's setPosition data is related to the Parent node. However, in Newton there is no such relationship so you must supply WORLD positions. But, in the Newton Transformation callbacks, newton supplies a position data (in Newton terms). This data is the WORLD position.

Why do I need this? I have a sun, with an orbiting planet, with a moon orbiting the planet. Planet is a child of the sun and the moon is a child of the planet.

How do I do a "setWorldPosition" on a node?

I saw this post
http://www.ogre3d.org/phpBB2/viewtopic. ... ldposition
but I can't see a second option in Node::setPosition.

User avatar
walaber
OGRE Expert User
OGRE Expert User
Posts: 829
Joined: Sat Oct 02, 2004 2:20 pm
Location: California, USA
Contact:

Post by walaber »

any particular reason you need to maintain that heirarchy?

why not just make each element it's own scene node, and eliminate the middle man?
Go Go Gadget OGRE!!
Image

Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

walaber wrote:any particular reason you need to maintain that heirarchy?

why not just make each element it's own scene node, and eliminate the middle man?
because that is the power of Ogre. If I don't use the "features" then I would be responsible for maintaining alot of data and doing alot of extra work. That doesn't make since... I don't want to use the lowest common denominator of the graphics engine.

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

How do I do a "setWorldPosition" on a node?
You don't. If you really want to do this then, when Newton returns the world positions for your body then you'll have to work out (yourself) what that is relative to the node's parent (and grandparent, etc...) and use that to set the node's position.
because that is the power of Ogre.

But that "power" is designed for when you want to control the nodes manually, so that when you move a parent, all its children move too.

When you're using a physics engine to control the node's positions then the relationships should be defined and enforced through the physics engine. So that joints and constraints define how nodes move in relation to each other, rather than the Ogre node heirarchy defining that movement.
If I don't use the "features" then I would be responsible for maintaining alot of data and doing alot of extra work.
Yes, if you were moving the nodes around manually. But you're not, you're using Newton to do it for you, so all the "extra" work of deciding where one node should be in relation to another is decided by Newton. It does all the extra work for you.

Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

here is how I got around the set world position in the Newton Transformation Callback

Code: Select all


void _cdecl clsNewtonFL::DefaultTransformCallback (const NewtonBody* nBody, const float* nMatrix)
{

Ogre::SceneNode *Node=NULL;
Ogre::Node *ParentNode=NULL;
Ogre::Quaternion oQuat(0,0,0,0), oParentQuat(0,0,0,0);
Ogre::Vector3 oPos(0,0,0), oParentWorldPos(0,0,0);

Node = NewtonBodyGetUserData(nBody);

// Translate Newton Matrix to Ogre Quaternion and Vector 3
MatrixToQuatPos(nMatrix, oQuat, oPos); // Credit to walaber for this function

// Determine parents real world position
ParentNode = Node->getParent();
if (ParentNode)
{
	
	// the the parents real world position
	oParentQuat = ParentNode->getWorldOrientation();
	oParentWorldPos = ParentNode->getWorldPosition();

	// Now, take the real world position from newton and the real world
	// position of the parent and derive a RELATIVE position.
	oQuat = oQuat - oParentQuat;
	oPos = oPos - oParentWorldPos;
}
		
// Position the node (relative to parent, if there is one)
Node->setOrientation(oQuat);		// set Ogre Orientation (rotation)
Node->setPosition(oPos);		// set Ogre Position

} // DefaultTransformCallback


Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

For those of you that may copy my code above to derive a real world position, you need to change the line:

oPos = oPos - oParentWorldPos;

to

oPos = (oPos - oParentWorldPos) / ParentNode->getScale();

User avatar
monster
OGRE Community Helper
OGRE Community Helper
Posts: 1098
Joined: Mon Sep 22, 2003 2:40 am
Location: Melbourne, Australia
Contact:

Post by monster »

Woo-hoo! The marvellously named Ogrewton (pronounced "Oh! grew tonne") lives!

Here's the "1000 stacked boxes demo" from Tutorial 2 reimplemented in Ogre;
Image
Any similarity to OgreOde is purely coincidental!

User avatar
Sputnick
Greenskin
Posts: 110
Joined: Wed Sep 08, 2004 11:49 pm
Location: Lausanne, Switzerland

Post by Sputnick »

monster wrote:Any similarity to OgreOde is purely coincidental!
To OgreOde or to Nogredex !

Nice work.

- Sput

User avatar
Robomaniac
Hobgoblin
Posts: 508
Joined: Tue Feb 03, 2004 6:39 am

Post by Robomaniac »

Go Monster, master of physics. WE bow before you!
phear hingo

My Webpage

Post Reply