Use ogreode to create a moving role

Source: Internet
Author: User

I believe that I am not the first to ask myself how to use ogreode to create a sports role. After searching for forums and wikis, I realized this was a useful piece of information. This tutorial explains how to create a sports role that can walk on the terrain (including other meshes, such as trees and houses ).

Create a physical model

I use the monster method to represent a role:

Next, I suppose you have some knowledge about scenenodes, meshes, and alignedboxes of ogre, and will use scenemanager to create a terrain.

Create a role

First, create a scenenode to place the role's mesh. In this example, I used the ninja model in the Ogre example. Create two scenenode and connect them together. I will explain why there are two nodes later.

View plaincopy to clipboardprint?
  1. Entity * ninja = mscenemgr-> createentity ("ninja", "ninja. mesh ");
  2. Scenenode * ninjanode = mscenemgr-> getrootscenenode ()-> createchildscenenode ("ninja ");
  3. Scenenode * modelnode = ninjanode-> createchildscenenode ("ninja_model ");
  4. Modelnode-> attachobject (ninja );
  5. Ninjanode-> setscale (0.05, 0.05, 0.05 );
  6. Rootscenenode
  7. Ninjanode
  8. Modelnode
Entity* ninja = mSceneMgr->createEntity("ninja","ninja.mesh");SceneNode* ninjaNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ninja");SceneNode* modelNode = ninjaNode->createChildSceneNode("ninja_model");modelNode->attachObject(ninja);ninjaNode->setScale(0.05,0.05,0.05);RootSceneNode ninjaNode modelNode

You may have noticed that ninjanode is scaled very small, because if the mesh is large, the rendering speed becomes very slow (I don't know why ).

Obtain AABB (axisalignedbox, axis alignment box)

Now, use axisalignedbox to obtain the mesh size.

View plaincopy to clipboardprint?
  1. Axisalignedbox AAB = modelnode-> getattachedobject ("ninja")-> getboundingbox ();
  2. Ogre: vector3 min = Aab. getminimum () * ninjanode-> getscale ();
  3. Ogre: vector3 max = Aab. getmaximum () * ninjanode-> getscale ();
  4. Ogre: vector3 center = Aab. getcenter () * ninjanode-> getscale ();
  5. Ogre: vector3 size (FABS (max. x-min.x), FABS (max. y-min.y), FABS (max. z-min.z ));
  6. FloatRadius = (size. x> size. Z )? Size. Z/2.0f: size. X/2.0f;
AxisAlignedBox aab = modelNode->getAttachedObject("ninja")->getBoundingBox();Ogre::Vector3 min = aab.getMinimum()*ninjaNode->getScale();Ogre::Vector3 max = aab.getMaximum()*ninjaNode->getScale();Ogre::Vector3 center = aab.getCenter()*ninjaNode->getScale();Ogre::Vector3 size(fabs(max.x-min.x),fabs(max.y-min.y),fabs(max.z-min.z));float radius = (size.x>size.z)?size.z/2.0f:size.x/2.0f;

Create a new space

We need to create a new space to place the role in it and cancel the internal collision detection.

View plaincopy to clipboardprint?
  1. Ogreode: simplespace * dollspace = new ogreode: simplespace (_ world-> getdefaspace space ());
  2. Dollspace-> setinternalcollisions (false );
OgreOde::SimpleSpace* dollSpace = new OgreOde::SimpleSpace(_world->getDefaultSpace());dollSpace->setInternalCollisions(false);

Create a sphere (LEG)

Now we have two scenenodes, "ninjanode" and "modelnode ". Ninjanode is the node that represents your role, and modelnode is the place where you actually paste the mesh. This is because the mesh center is always in the center of ogreode: body, so we use ninjanode to create the position of the collision body, and then according to ninjanode and ogreode :: body to obtain the correct position of the mesh.

The figure on the left shows the effect obtained by using a scenenode, and two scenenode on the right. You can notice that the role on the left is suspended in the air. The following code creates a sphere that represents the role's foot. We need a spheregeometry and a transformgeometry to place the sphere in the correct position.

Note: My conjecture. I don't know how complicated the process is. Please correct it.

(1) create a collision body named feet

(2) set the collision body to a spherical object and the radius obtained by AABB

(3) spheregeometry. The radius is the radius obtained by AABB.

(4) transformgeometry. The space is the space just created. transformgeometry seems to be used to contain a specific shape of the ry.

(5) change the position of modelnode relative to ninjianode so that the foot can take over the ground.

(6) Let transformgeometry contain an ogreode: body and a ry

(7) stick the Ogre: Body to ninjanode.

Check whether the creation of spheregeometry only targets the Ogre: body.

View plaincopy to clipboardprint?
  1. Ogreode: body * dollfeetbody = new ogreode: Body ("feet ");
  2. Dollfeetbody-> setmass (ogreode: spheremass (70*2.5, radius ));
  3. Ogreode: spheregeometry * feetgeom = new ogreode: spheregeometry (RADIUS );
  4. Ogreode: transformgeometry * feettrans = new ogreode: transformgeometry (dollspace );
  5. Modelnode-> translate (vector3 (0,-radius/ninjanode-> getscale (). Y, 0 ));
  6. Feettrans-> setbody (dollfeetbody );
  7. Feettrans-> setencapsulatedgeometry (feetgeom );
  8. Ninjanode-> attachobject (dollfeetbody );
OgreOde::Body* dollFeetBody = new OgreOde::Body("feet");  dollFeetBody->setMass(OgreOde::SphereMass(70*2.5,radius));OgreOde::SphereGeometry* feetGeom = new OgreOde::SphereGeometry(radius);OgreOde::TransformGeometry* feetTrans = new OgreOde::TransformGeometry(dollSpace);modelNode->translate(Vector3(0,-radius/ninjaNode->getScale().y,0));feetTrans->setBody(dollFeetBody);feetTrans->setEncapsulatedGeometry(feetGeom);ninjaNode->attachObject(dollFeetBody);

Create an elliptical body

The upper half of a role is represented by an elliptical body.

Same as above.

(1) Create ogre: Body

(2) Set ogre: Body Shape. In addition, it is not affected by gravity,

(3) create transformgeometry. The space is the space just created.

(4) create a capsulegeometry with the radius aabb to obtain the radius.

(5) set the capsulegeometry position and direction and Damping

(6) Let transformgeometry include ogre: Body

(7) Let transformgeometry include capsulegeometry

(8) stick the Ogre: Body to ninjianode.

View plaincopy to clipboardprint?
  1. Ogreode: body * dolltorsobody = new ogreode: Body ("Torso ");
  2. Dolltorsobody-> setmass (ogreode: capsulemass (70*2.5, radius, vector3: unit_y, radius ));
  3. Dolltorsobody-> setaffectedbygravity (false );
  4. Dolltorsobody-> setdamping );
  5. Ogreode: transformgeometry * torsotrans = new ogreode: transformgeometry (dollspace );
  6. Ogreode: capsulegeometry * torsogeom = new ogreode: capsulegeometry (radius, size. y-4 * radius, dollspace );
  7. Torsogeom-> setposition (Ogre: vector3 (0, size. y-(size. y-4 * radius)/2 + 2 * radius), 0); // can't find a good way to explain this
  8. Torsogeom-> setorientation (quaternion (degree (90), vector3: unit_x ));
  9. Torsotrans-> setbody (dolltorsobody );
  10. Torsotrans-> setencapsulatedgeometry (torsogeom );
  11. Ninjanode-> attachobject (dolltorsobody );
OgreOde::Body* dollTorsoBody = new OgreOde::Body("torso");dollTorsoBody->setMass(OgreOde::CapsuleMass(70*2.5,radius,Vector3::UNIT_Y,radius));dollTorsoBody->setAffectedByGravity(false);dollTorsoBody->setDamping(0,50000);OgreOde::TransformGeometry* torsoTrans = new OgreOde::TransformGeometry(dollSpace);OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry(radius,size.y-4*radius,dollSpace);torsoGeom->setPosition(Ogre::Vector3(0,size.y-((size.y-4*radius)/2+2*radius),0)); //can't find a good way to explain thistorsoGeom->setOrientation(Quaternion(Degree(90),Vector3::UNIT_X));torsoTrans->setBody(dollTorsoBody);torsoTrans->setEncapsulatedGeometry(torsoGeom);ninjaNode->attachObject(dollTorsoBody);

This ry is in the same space as the ry, so we need to cancel the internal collision detection. The damping setting is higher and the gravity is removed, otherwise it will fall down from the sphere.

Create joint

The rest is to link the two collision bodies. A twisted connection represents the front wheel of a bicycle.

View plaincopy to clipboardprint?
  1. Ogreode: hingejoint * Joint = new ogreode: hingejoint ();
  2. Joint-> attach (dolltorsobody, dollfeetbody );
  3. Joint-> setaxis (Ogre: vector3: unit_x); // set the Rotation Axis
OgreOde::HingeJoint* joint = new OgreOde::HingeJoint();joint->attach(dollTorsoBody,dollFeetBody);joint->setAxis(Ogre::Vector3::UNIT_X);      //set the rotation axis

Note: Do not forget to record all collision bodies and connection locations so that you can get them later. You can use the Ogre stack or create your own.

Mobile role

You can move or rotate your role in different ways. I decided to change the direction of the collision body rather than apply the force or torque.

Move before and after

The following code can be executed in a key response, such as kc_up. Now you need to get the collision body from the stack or hashtable, and then get its direction. My use:

Note: the conjecture stack is a list of the Ogre: body you have created for all objects on the screen.

View plaincopy to clipboardprint?
  1. Ogreode: body * torso = torsobodies-> GetObject ("ninja ");
  2. Quaternion q = torso-> getorientation ();
OgreOde::Body* torso = torsoBodies->getObject("ninja");Quaternion q = torso->getOrientation();

Then, assign the foot an angular velocity.

View plaincopy to clipboardprint?
  1. Ogreode: body * feet = feetbodies-> GetObject ("ninja ");
  2. Feet-> wake ();
  3. Feet-> setangularvelocity (Q * ogre: vector3 (10 * Cos (1), 0, 10 * sin (1 )));
OgreOde::Body* feet = feetBodies->getObject("ninja");feet->wake();feet->setAngularVelocity(q*Ogre::Vector3(10*cos(1),0,10*sin(1)));

10 is the angular velocity we use. We must multiply the trigonometric function to let the role forward in the correct direction.

Rotate left and right

The following code is also executed in the key response, such as kc_right.

View plaincopy to clipboardprint?
  1. Ogreode: body * torso = torsobodies-> GetObject ("ninja ");
  2. Quaternion Q1 = torso-> getorientation ();
  3. Quaternion Q2 (degree (-4), ogre: vector3: unit_y );
  4. Torso-> setorientation (Q1 * q2 );
OgreOde::Body* torso = torsoBodies->getObject("ninja");Quaternion q1 = torso->getOrientation();Quaternion q2(Degree(-4),Ogre::Vector3::UNIT_Y);torso->setOrientation(q1*q2);

Use degree (-4) to turn the role to the right, and use positive numbers to turn left. You may have noticed that I always get or set the direction from the elliptical body. I don't think much about it. I think there should be no problem if you get and set it from the sphere of your feet.

Note: If you release the button, you must set the speed to 0 to stop the motion.

View plaincopy to clipboardprint?
  1. Feetbody-> setangularvelocity (vector3 (0, 0 ));
  2. Feetbody-> setlinearvelocity (vector3 (0, feetbody-> getlinearvelocity (). Y, 0 ));
feetbody->setAngularVelocity(Vector3(0,0,0));feetBody->setLinearVelocity(Vector3(0,feetBody->getLinearVelocity().y,0));

Get a role up

Finally, we need to make sure that your role does not fall, so we need to reset its vertical direction from time to time.

View plaincopy to clipboardprint?
  1. Ogreode: body * torso = torsobodies-> GetObject ("ninja ");
  2. Quaternion q = torso-> getorientation ();
  3. Vector3 x = Q. xaxis ();
  4. Vector3 y = Q. yaxis ();
  5. Vector3 z = Q. zaxis ();
  6. Torso-> wake ();
  7. Torso-> setorientation (quaternion (x, vector3: unit_y, z ));
OgreOde::Body* torso = torsoBodies->getObject("ninja");Quaternion q = torso->getOrientation();                      Vector3 x = q.xAxis();Vector3 y = q.yAxis();Vector3 z = q.zAxis(); torso->wake();torso->setOrientation(Quaternion(x,Vector3::UNIT_Y,z));

Problem

Some code is not as good as I think. Resetting the vertical direction will make the role behave strangely. Although I set the speed to 0, the role still cannot stop on some irregular surfaces.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.