Code Snippets and Tips

Wretched_Wyx

24-08-2006 00:39:19

Have a cool feature you've implemented that you'd like to share? A general (or specific) tip? Post them here for the world to see. You might get famous and have Betajaen re-name one of his numerous pets after you.

*Note - Make sure to use the code tags for your code. People get lazy with that sometimes. And give good documentation on what your code/tip is all about, how it works, etc!

betajaen

24-08-2006 00:43:31

Betajaen's Top Tip!

Ever wanted to have a SceneNode to face the same direction as a SceneNode, but be slightly offset? Attaching that SceneNode to the other would be to easy, but in some cases it won't be possible.

What happens if that SceneNode is another kinetic body and character; perhaps that character is holding that body? This is where Betajaen's top tip comes in!

Vector3 offset = Vector3(1,2,3);
target->setPosition(
source->getPosition() + (source->getOrientation() * offset)
);

BlasterN

25-08-2006 02:13:25

Mesh To ConvexShape.
The LOD support is near, but have to wait a little.

Thread: http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=1861

I dont know if betajaen include it into the core.


Betajaen says: It's already in :)

DaCracker

27-08-2006 12:27:35

Using nxOgre with oFusion

I discoverd a small problem when using nxOgre with oFusion. Both of them wants to create their own scene node. oFusion adds properties like scale and rotation to it's nodes, properties that will be lost when using nxOgre, since it only accepts a position when it creates it's own SceneNode.

To solve this I made some changes to the body and the scene class.

First of all, I added a new constructor to the body class, which can accept a SceneNode

in nxOgre_body.h:

class body
{
//some code...
body(Ogre::String _name,nxOgre::scene *_scene,Ogre::String _meshName, nxOgre::shape *_shape,float _density,Ogre::SceneNode *_mNode,bodyTypes _type = body::DYNAMIC);
//some more code...
};


Simply add the new constructor below the other constructors.

the next step is to add som code to the new constructor

In nxOgre_body.cpp

body::body(Ogre::String _name, nxOgre::scene *_scene, Ogre::String _meshName, nxOgre::shape *_shape, float _density, Ogre::SceneNode *_mNode, bodyTypes _type)
{
mName = _name;
owner = _scene;
mType = _type;
mAge = 0;
mAutoDelete = false;

//extern_node = true;

NxBodyDesc mBodyDescription;
NxActorDesc mActorDescription;
mActorDescription.setToDefault();
mBodyDescription.setToDefault();


mNode = _mNode;

if (_meshName != "") {
mEntity = owner->mSceneMgr->createEntity(mName, _meshName);
mEntity->setCastShadows(true);

mNode->attachObject(mEntity);

}

//the rest of the code should be like the first constructor, exept
//the changes to it above until line 189, remove the code
which looks like this:
//mActorDescription.globalPose.t = _pos.getVec3();
//mActorDescription.globalPose.M.fromQuat(_pos.getQuat());
//and add this code instead:
NxVec3 v;

v.set(mNode->getPosition().x,mNode->getPosition().y,mNode->getPosition().z);

NxQuat q;

q.setWXYZ(mNode->getOrientation().w,mNode->getOrientation().x,mNode->getOrientation().y,mNode->getOrientation().z);

mActorDescription.globalPose.t = v;
mActorDescription.globalPose.M.fromQuat(q);

//the rest of the code is the same as the first constructor

//end of the constructor
}


The only thing that's left now is to overload a method
in the scene class! I choose to only overload the createStaticBody method, but it should be a problem for you to overload the createBody method
if you wish.

Now, make those changes to the nxOgre_scene.h file:

class scene
{
//some code
body* createStaticBody(Ogre::String _name, Ogre::String _meshName,nxOgre::shape *_shape,Ogre::SceneNode *_Node);
//some more code
};


And finally in the nxOgre_scene.cpp file:

body* scene::createStaticBody(Ogre::String _name,Ogre::String _meshName,nxOgre::shape *_shape,Ogre::SceneNode *_mNode)
{
isEmpty = false;
body* b = new body(_name,this,_meshName,_shape,0,_mNode,body::STATIC);
this->mBody.push_back(b);
return b;
}


Add the code below the other createStaticBody, or somewere else

:)

Now you can easily create a nxOgre::body with the oFusion code by simply sending the SceneNode you get in the createEntity to the scene::createStaticBody method!

Happy coding :)

M@gg!

26-09-2006 12:53:03

Storage system for preloading bullets or other frequently (or not so frequently) used stuff.

It can be used to store nearly each object you like in it. The key feature is, that you can easily preload a huge amount of identicaly objects and can access them when ever you like (it's an Ogre::Singleton).

The Magazine Storage is a framelistener, that updates your objects (if you like) each framend with the elapsed time since the last frame.


More details and source code you can find in this thread:
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=2295

Aiursrage2k

05-10-2007 05:40:34

1: Making an elevator that lifts a character.
Working under the Assumptions
Gravity is applied in the negative y-axis.
The elevator is a simple shape -- ie a box.

Create two actor groups called elevator and unitContact.
Set them up for contact using onTouch and onStartTouch

Derive your class from NxOgre::Character
->set the setMovementVectorController to the derived class
->create another actor that is the same dimension type (capsule/box) as your character
->>Set its userGroup to unitContact,
->>Raise the actor flag NX_AF_DISABLE_RESPONSE
->>Every frame move it to the position of the character.

For the elevator, make it kinematic, sets it actor group to elevator.



//in the character constructor
NxOgre::ShapeBlueprint* bp = 0;
Vector3 dim = NxOgre::toVector3(cp.mDimensions);
int actorFlag = NX_AF_DISABLE_RESPONSE;

if(cp.mType == cp.CT_Capsule)
{
bp = new NxOgre::CapsuleShape(dim.x,dim.y*2);
}else{
bp = new NxOgre::CubeShape(dim.x,dim.y,dim.z);
}
m_actor = scene->createActor("Sphere",bp,pose);
m_actor->raiseActorFlag((NxActorFlag)actorFlag );
m_actor->setGroup(COLLSION_GROUP_UNIT_CONTACT);
m_actor->getNxActor()->userData
= new MyUserData(m_actor,NxActorUserData::T_Actor,OBJECT_TYPE_UNIT,this);


//same thing for onStartTouch
virtual void onTouch(Actor* a1,
Actor* a2)
{
Elevator* elevator=getPtr<Elevator*>(a1,a2,COLLSION_GROUP_ELEVATOR);
TestObject2* unitContact=getPtr<TestObject2*>(a1,a2,COLLSION_GROUP_UNIT_CONTACT);

if(elevator && unitContact)
{
unitContact->addElevatorForce(elevator->getDeltaForce());
}
}

template <class T>
static T getPtr(Actor* a1,
Actor* a2,
const std::string& type)
{
T ptr = 0;
MyUserData* m1 = (MyUserData*)a1->getNxActor()->userData;
MyUserData* m2 = (MyUserData*)a2->getNxActor()->userData;
if(a1->getGroup()->getName()==type)
{
ptr = (T)m1->myControl;
}
if(a2->getGroup()->getName()==type)
{
ptr = (T)m2->myControl;
}
return ptr;
}

struct MyUserData : public NxOgre::NxActorUserData
{
int myType;
void* myControl;
}

void TestObject2::addElevatorForce(const Vector3& vec)
{
m_onElevator = true;
m_elevatorImpulseForce = vec;
}
void TestObject2::move(NxVec3 &out,
NxVec3 &moveVector,
NxQuat &direction,
NxVec3 &g,
float t,
Character*)
{
update(t);

if(m_onElevator && m_elevatorImpulseForce.y >0 && m_constantForce.y <=0)
{
out = (moveVector*m_movSpeed) * t + NxOgre::toNxVec3(m_impulseForce);
}else{
out = (moveVector*4.0 + g) * t
+ NxOgre::toNxVec3(m_sumForces);
}

m_elevatorImpulseForce = Vector3(0,0,0);
m_moveImpulseForce = Vector3(0,0,0);
m_impulseForce = Vector3(0,0,0);

m_onElevator=false;
}


NOTE:
It might be improved by getting more information from the contact report. For example using the normal to detect if you are on top of the 'box' and to disregard if you are not.

jchmack

06-10-2007 14:27:21

nice aiurs =) been looking for a good answer. Ill try it out =)

katzenjoghurt

11-10-2007 21:29:11

No great magic.
Just some snippet to facilitate terrain loading and keeping physical and rendered terrain 1:1 without having to synchronise code and config file all the time while fiddling around with heightmaps. (Synchronizing which everyone hates to do. :D )


String terrainCfgFile = "terrain.cfg";

...

mSceneMgr->setWorldGeometry(terrainCfgFile );
...

Ogre::ConfigFile* terrainCfg;
terrainCfg = new Ogre::ConfigFile();
terrainCfg->loadFromResourceSystem(terrainCfgFile , "General");

int pageSize = StringConverter::parseInt(terrainCfg->getSetting("PageSize"));
float PageWorldX = StringConverter::parseReal(terrainCfg->getSetting("PageWorldX"));
float PageWorldZ = StringConverter::parseReal(terrainCfg->getSetting("PageWorldZ"));
float maxHeight = StringConverter::parseReal(terrainCfg->getSetting("MaxHeight"));
String heightmap = terrainCfg->getSetting("Heightmap.image");

Vector3 terrainScale;
terrainScale.x = PageWorldX/(pageSize-1);
terrainScale.z = PageWorldZ/(pageSize-1);

String scaleString = "mesh-scale: " + StringConverter::toString(terrainScale.x) + " 1 " + StringConverter::toString(terrainScale.z);

NxOgre::Actor* mGround;
mGround = mScene->createActor("terrain", new NxOgre::TerrainShape(heightmap, maxHeight, scaleString), Vector3::ZERO, "static: yes");

delete terrainCfg;
terrainCfg = NULL;

betajaen

11-10-2007 22:43:57

Nice bit of code there. I've rewritten it as a function if you don't mind. It's untested but it compiles:

NxOgre::Actor* createTerrainFromWorldGeometry(
const NxOgre::NxString& terrainConfigurationFilename,
NxOgre::Scene* scene,
NxOgre::Pose& pose = NxOgre::Pose(),
const NxOgre::NxString& actorParams = "static: yes",
const NxOgre::NxString& shapeParams = ""
) {

scene->getSceneManager()->setWorldGeometry(terrainConfigurationFilename);


Ogre::ConfigFile* terrainCfg;
terrainCfg = new Ogre::ConfigFile();
terrainCfg->loadFromResourceSystem(terrainConfigurationFilename,
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
);

int pageSize = Ogre::StringConverter::parseInt(terrainCfg->getSetting("PageSize"));
float PageWorldX = Ogre::StringConverter::parseReal(terrainCfg->getSetting("PageWorldX"));
float PageWorldZ = Ogre::StringConverter::parseReal(terrainCfg->getSetting("PageWorldZ"));
float maxHeight = Ogre::StringConverter::parseReal(terrainCfg->getSetting("MaxHeight"));
Ogre::String heightmap = terrainCfg->getSetting("Heightmap.image");

NxOgre::ShapeParams sp(shapeParams);
sp.mMeshScale.x = PageWorldX/(pageSize-1);
sp.mMeshScale.y = 1;
sp.mMeshScale.z = PageWorldZ/(pageSize-1);

NxOgre::Actor* terrain = scene->createActor(
NxOgre::NxCreateID(scene->getNbActors(), heightmap),
new NxOgre::TerrainShape(heightmap, maxHeight, sp), pose, actorParams
);

delete terrainCfg;

return terrain;
}

TMT

12-10-2007 18:17:56

I was planning on do this exact thing. Thanks guys for doing it before I got to it.

dbrock

03-12-2007 15:40:23

Nice bit of code there. I've rewritten it as a function if you don't mind. It's untested but it compiles:

NxOgre::Actor* createTerrainFromWorldGeometry(
const NxOgre::NxString& terrainConfigurationFilename,
NxOgre::Scene* scene,
NxOgre::Pose& pose = NxOgre::Pose(),
const NxOgre::NxString& actorParams = "static: yes",
const NxOgre::NxString& shapeParams = ""
) {

scene->getSceneManager()->setWorldGeometry(terrainConfigurationFilename);


Ogre::ConfigFile* terrainCfg;
terrainCfg = new Ogre::ConfigFile();
terrainCfg->loadFromResourceSystem(terrainConfigurationFilename,
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
);

int pageSize = Ogre::StringConverter::parseInt(terrainCfg->getSetting("PageSize"));
float PageWorldX = Ogre::StringConverter::parseReal(terrainCfg->getSetting("PageWorldX"));
float PageWorldZ = Ogre::StringConverter::parseReal(terrainCfg->getSetting("PageWorldZ"));
float maxHeight = Ogre::StringConverter::parseReal(terrainCfg->getSetting("MaxHeight"));
Ogre::String heightmap = terrainCfg->getSetting("Heightmap.image");

NxOgre::ShapeParams sp(shapeParams);
sp.mMeshScale.x = PageWorldX/(pageSize-1);
sp.mMeshScale.y = 1;
sp.mMeshScale.z = PageWorldZ/(pageSize-1);

NxOgre::Actor* terrain = scene->createActor(
NxOgre::NxCreateID(scene->getNbActors(), heightmap),
new NxOgre::TerrainShape(heightmap, maxHeight, sp), pose, actorParams
);

delete terrainCfg;

return terrain;
}


If your terrain is deformable, would it be ideal to delete and re-create the terrain actor upon generation of the latest heightmap image? or is there a simpler way to update this?

The reason I'm asking is my level editor can deform terrain, and I was thinking that I should create all the phys objects in the editor, and use the xml serializer to save the scene. There won't be any physics updating besides re-position the objects if they fall through the terrain, but besides that, they won't need to have any real-time physics behavior yet.

bens1404

01-01-2008 18:01:33

Using nxOgre with oFusion

Happy coding :)


but bodyTypes _and other variable nType,mAge dont exist in the body class
iam using the latest version from svc
please tell me how to work with ofusion scen with latest nxogre version 0.9'39

betajaen

01-01-2008 18:25:29

Sigh. Can't you just be normal and open a new thread about it?

bens1404

01-01-2008 19:38:22

Sigh. Can't you just be normal and open a new thread about it?


ok sorry ill do that