Add a bullet Shape Loader

actorid
gugus 14 years ago
parent 940554b5fc
commit a8ade56c80

@ -81,6 +81,12 @@ set(NIFOGRE_HEADER
${COMP_DIR}/nifogre/ogre_nif_loader.hpp)
source_group(components\\nifogre FILES ${NIFOGRE} ${NIFOGRE_HEADER})
set(NIFBULLET
${COMP_DIR}/nifbullet/ogre_bullet_loader.cpp)
set(NIFBULLET_HEADER
${COMP_DIR}/nifbullet/bullet_nif_loader.hpp)
source_group(components\\nifbullet FILES ${NIFBULLET} ${NIFBULLET_HEADER})
set(TO_UTF8
${COMP_DIR}/to_utf8/to_utf8.cpp)
set(TO_UTF8_HEADER

@ -83,7 +83,6 @@ void NIFFile::parse()
// NiNodes
if(rec == "NiNode" || rec == "AvoidNode" ||
rec == "RootCollisionNode" ||
rec == "NiBSParticleNode" ||
rec == "NiBSAnimationNode" ||
rec == "NiBillboardNode") { r = new NiNode; r->recType = RC_NiNode; }
@ -93,6 +92,8 @@ void NIFFile::parse()
else if(rec == "NiRotatingParticles") { r = new NiRotatingParticles; r->recType = RC_NiRotatingParticles; }
else if(rec == "NiAutoNormalParticles") { r = new NiAutoNormalParticles; r->recType = RC_NiAutoNormalParticles; }
else if(rec == "NiCamera") { r = new NiCamera; r->recType = RC_NiCamera; }
else if(rec == "RootCollisionNode"){ r = new NiNode; r->recType = RC_RootCollisionNode; }// a root collision node is exactly like a node
//that's why there is no need to create a new type
// Properties
else if(rec == "NiTexturingProperty") { r = new NiTexturingProperty; r->recType = RC_NiTexturingProperty; }

@ -79,7 +79,8 @@ enum RecordType
RC_NiAutoNormalParticlesData,
RC_NiSequenceStreamHelper,
RC_NiSourceTexture,
RC_NiSkinInstance
RC_NiSkinInstance,
RC_RootCollisionNode
};
/// Base class for all records

@ -0,0 +1,386 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.sourceforge.net/
This file (ogre_nif_loader.cpp) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#include "bullet_nif_loader.hpp"
#include <Ogre.h>
#include <stdio.h>
#include <libs/mangle/vfs/servers/ogre_vfs.hpp>
#include "../nif/nif_file.hpp"
#include "../nif/node.hpp"
#include "../nif/data.hpp"
#include "../nif/property.hpp"
#include "../nif/controller.hpp"
#include "../nif/extra.hpp"
#include <libs/platform/strings.h>
#include <vector>
#include <list>
// For warning messages
#include <iostream>
// float infinity
#include <limits>
typedef unsigned char ubyte;
using namespace std;
using namespace Ogre;
using namespace Nif;
using namespace Mangle::VFS;
BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name,
Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual,
Ogre::ManualResourceLoader *loader) :
Ogre::Resource(creator, name, handle, group, isManual, loader)
{
/* If you were storing a pointer to an object, then you would set that pointer to NULL here.
*/
/* For consistency with StringInterface, but we don't add any parameters here
That's because the Resource implementation of StringInterface is to
list all the options that need to be set before loading, of which
we have none as such. Full details can be set through scripts.
*/
Shape = NULL;
createParamDictionary("BulletShape");
}
BulletShape::~BulletShape()
{
}
// farm out to BulletShapeLoader
void BulletShape::loadImpl()
{
mLoader->loadResource(this);
}
void BulletShape::deleteShape(btCollisionShape* mShape)
{
if(mShape!=NULL)
{
if(mShape->isCompound())
{
btCompoundShape* ms = static_cast<btCompoundShape*>(Shape);
btCompoundShapeChild* child = ms->getChildList();
int a = ms->getNumChildShapes();
for(int i=0; i <a;i++)
{
deleteShape(ms->getChildShape(i));
}
}
delete mShape;
}
mShape = NULL;
}
void BulletShape::unloadImpl()
{
deleteShape(Shape);
}
//TODO:change this?
size_t BulletShape::calculateSize() const
{
return 1;
}
//=============================================================================================================
template<> BulletShapeManager *Ogre::Singleton<BulletShapeManager>::ms_Singleton = 0;
BulletShapeManager *BulletShapeManager::getSingletonPtr()
{
return ms_Singleton;
}
BulletShapeManager &BulletShapeManager::getSingleton()
{
assert(ms_Singleton);
return(*ms_Singleton);
}
BulletShapeManager::BulletShapeManager()
{
mResourceType = "BulletShape";
// low, because it will likely reference other resources
mLoadOrder = 30.0f;
// this is how we register the ResourceManager with OGRE
Ogre::ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
}
BulletShapeManager::~BulletShapeManager()
{
// and this is how we unregister it
Ogre::ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
}
BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::String &group)
{
BulletShapePtr textf = getByName(name);
if (textf.isNull())
textf = create(name, group);
textf->load();
return textf;
}
Ogre::Resource *BulletShapeManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle,
const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
const Ogre::NameValuePairList *createParams)
{
BulletShape* res = new BulletShape(this, name, handle, group, isManual, loader);
//if(isManual)
//{
//loader->loadResource(res);
//}
return res;
}
//====================================================================================================
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
{
Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2],
tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2],
tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]);
return rot;
}
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
{
Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]);
return vect3;
}
btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m)
{
Ogre::Quaternion oquat(m);
btQuaternion quat;
quat.setW(oquat.w);
quat.setX(oquat.x);
quat.setY(oquat.y);
quat.setZ(oquat.z);
return quat;
}
btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v)
{
btVector3 a(v.array[0],v.array[1],v.array[2]);
return a;
}
void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
{
cShape = static_cast<BulletShape *>(resource);
resourceName = cShape->getName();
currentShape = new btCompoundShape();
cShape->Shape = currentShape;
if (!vfs) vfs = new OgreVFS(resourceGroup);
if (!vfs->isFile(resourceName))
{
warn("File not found.");
return;
}
// Load the NIF. TODO: Wrap this in a try-catch block once we're out
// of the early stages of development. Right now we WANT to catch
// every error as early and intrusively as possible, as it's most
// likely a sign of incomplete code rather than faulty input.
Nif::NIFFile nif(vfs->open(resourceName), resourceName);
if (nif.numRecords() < 1)
{
warn("Found no records in NIF.");
return;
}
// The first record is assumed to be the root node
Nif::Record *r = nif.getRecord(0);
assert(r != NULL);
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
if (node == NULL)
{
warn("First record in file was not a node, but a " +
r->recName.toString() + ". Skipping file.");
return;
}
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,false);
}
void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool isCollisionNode)
{
// Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least.
flags |= node->flags;
// Check for extra data
Nif::Extra *e = node;
while (!e->extra.empty())
{
// Get the next extra data in the list
e = e->extra.getPtr();
assert(e != NULL);
if (e->recType == Nif::RC_NiStringExtraData)
{
// String markers may contain important information
// affecting the entire subtree of this node
Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e;
if (sd->string == "NCO")
{
// No collision. Use an internal flag setting to mark this.
// We ignor this node!
flags |= 0x800;
return;
}
else if (sd->string == "MRK")
// Marker objects. These are only visible in the
// editor. Until and unless we add an editor component to
// the engine, just skip this entire node.
return;
}
}
//transfo of parents node + curent node
Ogre::Matrix3 finalRot;
Ogre::Vector3 finalPos;
float finalScale;
Nif::Transformation &final = *((Nif::Transformation*)node->trafo);
Ogre::Vector3 nodePos = getVector(&final);
Ogre::Matrix3 nodeRot = getMatrix(&final);
finalPos = nodePos + parentPos;
finalRot = parentRot*nodeRot;
finalScale = final.scale*parentScale;
// For NiNodes, loop through children
if (node->recType == Nif::RC_NiNode)
{
Nif::NodeList &list = ((Nif::NiNode*)node)->children;
int n = list.length();
for (int i=0; i<n; i++)
{
if (list.has(i))
handleNode(&list[i], flags,finalRot,finalPos,finalScale,isCollisionNode);
}
}
else if (node->recType == Nif::RC_NiTriShape && isCollisionNode) handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,finalRot,finalPos,finalScale);
else if(node->recType = Nif::RC_RootCollisionNode)
{
Nif::NodeList &list = ((Nif::NiNode*)node)->children;
int n = list.length();
for (int i=0; i<n; i++)
{
if (list.has(i))
handleNode(&list[i], flags,finalRot,finalPos,finalScale,true);
}
}
}
void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale)
{
assert(shape != NULL);
btCollisionShape* NodeShape;
// Interpret flags
bool hidden = (flags & 0x01) != 0; // Not displayed
bool collide = (flags & 0x02) != 0; // Use mesh for collision
bool bbcollide = (flags & 0x04) != 0; // Use bounding box for collision
// If the object was marked "NCO" earlier, it shouldn't collide with
// anything. So don't do anything.
if (flags & 0x800)
{
collide = false;
bbcollide = false;
return;
}
if (!collide && !bbcollide && hidden)
// This mesh apparently isn't being used for anything, so don't
// bother setting it up.
return;
btTransform tr;
tr.setRotation(getbtQuat(parentRot));
tr.setOrigin(btVector3(parentPos.x,parentPos.y,parentPos.z));
// Bounding box collision isn't implemented, always use mesh for now.
/*if (bbcollide)
{
return;
std::cout << "bbcolide?";
//TODO: check whether it's half box or not (is there a /2?)
NodeShape = new btBoxShape(btVector3(shape->boundXYZ->array[0]/2.,shape->boundXYZ->array[1]/2.,shape->boundXYZ->array[2]/2.));
std::cout << "bbcolide12121212121";
currentShape->addChildShape(tr,NodeShape);
std::cout << "aaaaaaaaaaaaa";
return;
collide = true;
bbcollide = false;
}*/
/* Do in-place transformation.the only needed transfo is the scale. (maybe not in fact)
*/
btTriangleMesh *mTriMesh = new btTriangleMesh();
Nif::NiTriShapeData *data = shape->data.getPtr();
int numVerts = data->vertices.length / 3;
float* vertices = (float*)data->vertices.ptr;
unsigned short* triangles = (unsigned short*)data->triangles.ptr;
for(int i=0; i < data->triangles.length; i = i+3)
{
btVector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
btVector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
btVector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale);
mTriMesh->addTriangle(b1,b2,b3);
}
NodeShape = new btBvhTriangleMeshShape(mTriMesh,true);
currentShape->addChildShape(tr,NodeShape);
}
void ManualBulletShapeLoader::load(const std::string &name,const std::string &group)
{
// Check if the resource already exists
Ogre::ResourcePtr ptr = BulletShapeManager::getSingleton().getByName(name, group);
if (!ptr.isNull())
return;
BulletShapeManager::getSingleton().create(name,group,true,this);
}

@ -0,0 +1,236 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.sourceforge.net/
This file (ogre_nif_loader.h) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#ifndef _BULLET_NIF_LOADER_H_
#define _BULLET_NIF_LOADER_H_
#include <OgreResource.h>
#include <OgreResourceManager.h>
#include <OgreMesh.h>
#include <assert.h>
#include <string>
#include <BulletCollision\CollisionShapes\btBvhTriangleMeshShape.h>
#include <BulletCollision\CollisionShapes\btConvexTriangleMeshShape.h>
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include <vector>
#include <list>
// For warning messages
#include <iostream>
// float infinity
#include <limits>
namespace Nif
{
class Node;
class Transformation;
class NiTriShape;
class Vector;
class Matrix;
}
namespace Mangle
{
namespace VFS
{
class OgreVFS;
}
}
/**
*Define a new resource which describe a Shape usable by bullet.See BulletShapeManager for how to get/use them.
*/
class BulletShape : public Ogre::Resource
{
Ogre::String mString;
protected:
void loadImpl();
void unloadImpl();
size_t calculateSize() const;
void deleteShape(btCollisionShape* mShape);
public:
BulletShape(Ogre::ResourceManager *creator, const Ogre::String &name,
Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual = false,
Ogre::ManualResourceLoader *loader = 0);
virtual ~BulletShape();
btCollisionShape* Shape;
};
/**
*
*/
class BulletShapePtr : public Ogre::SharedPtr<BulletShape>
{
public:
BulletShapePtr() : Ogre::SharedPtr<BulletShape>() {}
explicit BulletShapePtr(BulletShape *rep) : Ogre::SharedPtr<BulletShape>(rep) {}
BulletShapePtr(const BulletShapePtr &r) : Ogre::SharedPtr<BulletShape>(r) {}
BulletShapePtr(const Ogre::ResourcePtr &r) : Ogre::SharedPtr<BulletShape>()
{
if( r.isNull() )
return;
// lock & copy other mutex pointer
OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
pRep = static_cast<BulletShape*>(r.getPointer());
pUseCount = r.useCountPointer();
useFreeMethod = r.freeMethod();
if (pUseCount)
{
++(*pUseCount);
}
}
/// Operator used to convert a ResourcePtr to a BulletShapePtr
BulletShapePtr& operator=(const Ogre::ResourcePtr& r)
{
if(pRep == static_cast<BulletShape*>(r.getPointer()))
return *this;
release();
if( r.isNull() )
return *this; // resource ptr is null, so the call to release above has done all we need to do.
// lock & copy other mutex pointer
OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
pRep = static_cast<BulletShape*>(r.getPointer());
pUseCount = r.useCountPointer();
useFreeMethod = r.freeMethod();
if (pUseCount)
{
++(*pUseCount);
}
return *this;
}
};
/**
*Hold any BulletShape that was created by the ManualBulletShapeLoader.
*
*To get a bulletShape, you must load it first.
*First, create a manualBulletShapeLoader. Then call ManualBulletShapeManager->load(). This create an "empty" resource.
*Then use BulletShapeManager->load(). This will fill the resource with the required info.
*To get the resource,use BulletShapeManager::getByName.
*When you use the resource no more, just use BulletShapeManager->unload(). It won't completly delete the resource, but it will
*"empty" it.This allow a better management of memory: when you are leaving a cell, just unload every useless shape.
*
*Alternatively, you can call BulletShape->load() in order to actually load the resource.
*When you are finished with it, just call BulletShape->unload().
*
*IMO: prefere the first methode, i am not completly sure about the 2nd.
*
*Important Note: i have no idea of what happen if you try to load two time the same resource without unloading.
*It won't crash, but it might lead to memory leaks(I don't know how Ogre handle this). So don't do it!
*/
class BulletShapeManager : public Ogre::ResourceManager, public Ogre::Singleton<BulletShapeManager>
{
protected:
// must implement this from ResourceManager's interface
Ogre::Resource *createImpl(const Ogre::String &name, Ogre::ResourceHandle handle,
const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
const Ogre::NameValuePairList *createParams);
public:
BulletShapeManager();
virtual ~BulletShapeManager();
virtual BulletShapePtr load(const Ogre::String &name, const Ogre::String &group);
static BulletShapeManager &getSingleton();
static BulletShapeManager *getSingletonPtr();
};
/**
*Load bulletShape from NIF files.
*/
class ManualBulletShapeLoader : public Ogre::ManualResourceLoader
{
public:
ManualBulletShapeLoader():resourceGroup("General"){vfs = 0;}
virtual ~ManualBulletShapeLoader() {}
void warn(std::string msg)
{
std::cerr << "NIFLoader: Warn:" << msg << "\n";
}
void fail(std::string msg)
{
std::cerr << "NIFLoader: Fail: "<< msg << std::endl;
assert(1);
}
/**
*This function should not be called manualy. Use load instead. (this is called by the BulletShapeManager when you use load).
*/
void loadResource(Ogre::Resource *resource);
/**
*This function load a new bulletShape from a NIF file into the BulletShapeManager.
*When the file is loaded, you can then use BulletShapeManager::getByName() to retrive the bulletShape.
*Warning: this function will just crash if the resourceGroup doesn't exist!
*/
void load(const std::string &name,const std::string &group);
private:
Ogre::Matrix3 getMatrix(Nif::Transformation* tr);
Ogre::Vector3 getVector(Nif::Transformation* tr);
btQuaternion getbtQuat(Ogre::Matrix3 m);
btVector3 getbtVector(Nif::Vector v);
/**
*Parse a node.
*/
void handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool isCollisionNode);
/**
*convert a NiTriShape to a bullet trishape.
*/
void handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales);
Mangle::VFS::OgreVFS *vfs;
std::string resourceName;
std::string resourceGroup;
BulletShape* cShape;//current shape
btCompoundShape* currentShape;//the shape curently under construction
};
#endif

@ -0,0 +1,209 @@
#include "bullet_nif_loader.hpp"
#include "..\nifogre\ogre_nif_loader.hpp"
#include "..\bsa\bsa_archive.hpp"
#include "..\nifogre\ogre_nif_loader.hpp"
#include <Ogre.h>
#include <OIS.h>
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include "BtOgrePG.h"
#include "BtOgreGP.h"
#include "BtOgreExtras.h"
const char* mesh = "meshes\\x\\ex_hlaalu_b_24.nif";
class MyMotionState : public btMotionState {
public:
MyMotionState(const btTransform &initialpos, Ogre::SceneNode *node) {
mVisibleobj = node;
mPos1 = initialpos;
node->setPosition(initialpos.getOrigin().x(),initialpos.getOrigin().y(),initialpos.getOrigin().z());
}
virtual ~MyMotionState() {
}
void setNode(Ogre::SceneNode *node) {
mVisibleobj = node;
}
virtual void getWorldTransform(btTransform &worldTrans) const {
worldTrans = mPos1;
}
virtual void setWorldTransform(const btTransform &worldTrans) {
if(NULL == mVisibleobj) return; // silently return before we set a node
btQuaternion rot = worldTrans.getRotation();
mVisibleobj->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
btVector3 pos = worldTrans.getOrigin();
mVisibleobj->setPosition(pos.x(), pos.y(), pos.z());
}
protected:
Ogre::SceneNode *mVisibleobj;
btTransform mPos1;
};
int main()
{
try
{
//Ogre stuff
Ogre::Root* pRoot = new Ogre::Root();
pRoot->showConfigDialog();
BulletShapeManager* manag = new BulletShapeManager();
Ogre::RenderWindow* win = pRoot->initialise(true,"test");
Ogre::SceneManager* scmg = pRoot->createSceneManager(Ogre::ST_GENERIC,"MonGestionnaireDeScene");
Ogre::Camera* pCamera = scmg->createCamera("test");
Ogre::Viewport* pViewport = win->addViewport(pCamera);
pCamera->setPosition(-50,0,0);
pCamera->setFarClipDistance(10000);
pCamera->setNearClipDistance(1.);
pCamera->lookAt(0,0,0);
//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C++/OgreSK/media/models","FileSystem","General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("","FileSystem","General");
/*Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C++/OgreSK/media/materials/scripts","FileSystem","General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C++/OgreSK/media/materials/textures","FileSystem","General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C++/OgreSK/media/materials/programs","FileSystem","General");*/
//OIS stuff
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;
win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
OIS::InputManager *pInputManager = OIS::InputManager::createInputSystem( pl );
OIS::Mouse *pMouse = static_cast<OIS::Mouse*>(pInputManager->createInputObject(OIS::OISMouse, false));
OIS::Keyboard* pKeyboard = static_cast<OIS::Keyboard*>(pInputManager->createInputObject(OIS::OISKeyboard, false));
unsigned int width, height, depth;
int top, left;
win->getMetrics(width, height, depth, left, top);
const OIS::MouseState &ms = pMouse->getMouseState();
ms.width = width;
ms.height = height;
//Ressources stuff
addBSA("Morrowind.bsa");
//Ogre::ResourceGroupManager::getSingleton().createResourceGroup("general");
Ogre::ResourcePtr ptr = BulletShapeManager::getSingleton().getByName(mesh,"General");
ManualBulletShapeLoader* ShapeLoader = new ManualBulletShapeLoader();
ShapeLoader->load(mesh,"General");
//BulletShapeManager::getSingleton().unload(mesh);
//ShapeLoader->load(mesh,"General");
NIFLoader::load(mesh);
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
//BulletShapeManager::getSingleton().
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General");
BulletShapeManager::getSingleton().load(mesh,"General");
BulletShapeManager::getSingleton().unload(mesh);
BulletShapeManager::getSingleton().load(mesh,"General");
BulletShapeManager::getSingleton().load(mesh,"General");
//shape->load();
//shape->unload();
//shape->load();
//Bullet init
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
// Set up the collision configuration and dispatcher
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
// The actual physics solver
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
// The world.
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,-10,0));
//le sol?
Ogre::SceneNode *node = scmg->getRootSceneNode()->createChildSceneNode("node");
Ogre::Entity *ent = scmg->createEntity("Mesh1",mesh);
node->attachObject(ent);
MyMotionState* mst = new MyMotionState(btTransform::getIdentity(),node);
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,mst,shape->Shape,btVector3(0,0,0));
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);
//une balle:
Ogre::SceneNode *node2 = scmg->getRootSceneNode()->createChildSceneNode("node2");
Ogre::Entity *ent2 = scmg->createEntity("Mesh2","ogrehead.mesh");
node2->attachObject(ent2);
node2->setPosition(0,500,0);
btTransform iT;
iT.setIdentity();
iT.setOrigin(btVector3(0,5000,0));
MyMotionState* mst2 = new MyMotionState(btTransform::getIdentity(),node2);
btSphereShape* sphereshape = new btSphereShape(10);
btRigidBody::btRigidBodyConstructionInfo sphereCI(10,mst2,sphereshape,btVector3(0,0,0));
btRigidBody* sphere = new btRigidBody(sphereCI);
dynamicsWorld->addRigidBody(sphere);
//btOgre!
BtOgre::DebugDrawer* mDebugDrawer = new BtOgre::DebugDrawer(scmg->getRootSceneNode(), dynamicsWorld);
dynamicsWorld->setDebugDrawer(mDebugDrawer);
Ogre::Timer timer;
timer.reset();
bool cont = true;
while(cont)
{
if(timer.getMilliseconds()>30)
{
pMouse->capture();
pKeyboard->capture();
Ogre::Vector3 a(0,0,0);
if(pKeyboard->isKeyDown(OIS::KC_UP))
{
a = a + Ogre::Vector3(0,0,-20);
}
if(pKeyboard->isKeyDown(OIS::KC_DOWN))
{
a = a + Ogre::Vector3(0,0,20);
}
if(pKeyboard->isKeyDown(OIS::KC_ESCAPE))
{
cont = false;
}
OIS::MouseState MS = pMouse->getMouseState();
pCamera->yaw(-Ogre::Degree(MS.X.rel));
pCamera->pitch(-Ogre::Degree(MS.Y.rel));
pCamera->moveRelative(a);
pRoot->renderOneFrame();
mDebugDrawer->step();
timer.reset();
dynamicsWorld->stepSimulation(0.03);
}
}
std::cout << "cool";
delete manag;
delete pRoot;
char a;
std::cin >> a;
}
catch(Ogre::Exception& e)
{
std::cout << e.getFullDescription();
char a;
std::cin >> a;
}
}
Loading…
Cancel
Save