IrrPhisx

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
Pinic
Posts: 21
Joined: Wed Mar 07, 2018 10:55 am

IrrPhisx

Post by Pinic »

Проблемы при компиляции "IrrPhisx" в Code Blocks.
How to fix?
Is there an IrrPhysx for version 1.8?

Code: Select all

||=== Build: Debug in Physics (compiler: GNU GCC Compiler) ===|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|19|error: '__int64' does not name a type|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|24|error: expected initializer before 'NxU64'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|101|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|103|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|104|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|105|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|106|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|107|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|108|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|109|error: 'NxI64' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|note: in definition of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|109|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|110|error: 'NxU64' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|note: in definition of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|110|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\Nx.h|66|error: 'size_t' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxSimpleTypes.h|114|note: in expansion of macro 'NX_COMPILE_TIME_ASSERT'|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|744|error: '_asm' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|742|warning: unused variable 'localCos' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|743|warning: unused variable 'local' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|744|error: '_asm' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|744|error: '_asm' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|742|warning: unused variable 'localCos' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|743|warning: unused variable 'local' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|742|warning: unused variable 'localCos' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|743|warning: unused variable 'local' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|744|error: '_asm' was not declared in this scope|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|742|warning: unused variable 'localCos' [-Wunused-variable]|
C:\Users\al_pi\Desktop\sdks\SDKs\Foundation\include\NxMath.h|743|warning: unused variable 'local' [-Wunused-variable]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.h||In constructor 'IrrPhysx::CCloth::CCloth(NxScene*, NxClothDesc&, IrrPhysx::CClothPhysxMesh*, const vector3df&)':|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.h|33|warning: 'IrrPhysx::CCloth::VertexRenderBuffer' will be initialized after [-Wreorder]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.h|29|warning:   'NxScene* IrrPhysx::CCloth::Scene' [-Wreorder]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.cpp|10|warning:   when initialized here [-Wreorder]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.cpp||In destructor 'IrrPhysx::CCloth::~CCloth()':|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.cpp|37|warning: deleting 'void*' is undefined [-Wdelete-incomplete]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CClothPhysxMesh.cpp|33|warning: 'virtual const c8* irr::scene::IBoneSceneNode::getBoneName() const' is deprecated [-Wdeprecated-declarations]|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CCloth.cpp|144|warning: 'virtual const c8* irr::scene::IBoneSceneNode::getBoneName() const' is deprecated [-Wdeprecated-declarations]|
C:\Users\al_pi\Desktop\Project\IrrRenderer\include\IBoneSceneNode.h|64|note: declared here|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CConvexPhysxMesh.cpp|18|warning: 'virtual const c8* irr::scene::IBoneSceneNode::getBoneName() const' is deprecated [-Wdeprecated-declarations]|
C:\Users\al_pi\Desktop\Project\IrrRenderer\include\IBoneSceneNode.h|64|note: declared here|
C:\Users\al_pi\Desktop\Project\IrrRenderer\include\IBoneSceneNode.h|64|note: declared here|
C:\Users\al_pi\Desktop\Project\Physics\SRC\CClothPhysxObject.cpp|199|warning: 'virtual const c8* irr::scene::IBoneSceneNode::getBoneName() const' is deprecated [-Wdeprecated-declarations]|
C:\Users\al_pi\Desktop\Project\IrrRenderer\include\IBoneSceneNode.h|64|note: declared here|
||=== Build failed: 18 error(s), 16 warning(s) (0 minute(s), 1 second(s)) ===|
 
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

It looks like you are using an older version of PhysX (since the names all have NX in them)
if you update to the latest PhysX version I can offer help....
Pinic
Posts: 21
Joined: Wed Mar 07, 2018 10:55 am

Re: IrrPhisx

Post by Pinic »

Seven wrote:It looks like you are using an older version of PhysX (since the names all have NX in them)
if you update to the latest PhysX version I can offer help....
Help please I have downloaded the latest version)) But IrrPhysx created based on the old version have Physx in the new version have a different structure.. I would be very grateful if you manage to collect IrrPhysx based on the new version))
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

I don’t use irrphysx but I do have fully functional physic 3.## code I can post when I get home tonight.
Pinic
Posts: 21
Joined: Wed Mar 07, 2018 10:55 am

Re: IrrPhisx

Post by Pinic »

Seven wrote:I don’t use irrphysx but I do have fully functional physic 3.## code I can post when I get home tonight.
I will be grateful if you share))
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

ok, some physX3.## code for Irrlicht.

create a manager to initialize physx

Code: Select all

 
        // instantiate, initialize and create the level manager
        m_PhysXManager = new FSPhysXManager();
        m_PhysXManager->initialize();
        if (!m_PhysXManager->create(getDevice(), getDriver())) { FS_LOG(FSL_ERROR, "unable to create FSPhysXManager"); return false; }
 
then create worlds to hold the objects ( FSOT_ are just defines for object types so you can setup which objects detect collisions with what other types of objects)
just use FSOT_ALL and FSOT_ALL if you want all objects to be able to collide

Code: Select all

 
#define FSOT_NONE       0x00000000
#define FSOT_ALL        0x11111111
#define FSOT_OBJECT 0x00000001
#define FSOT_TERRAIN    0x00000010
#define FSOT_STATIC     0x00000100
#define FSOT_SKYBOX 0x00001000
#define FSOT_LIGHT      0x00010000
#define FSOT_TRIGGER    0x00100000
#define FSOT_WATER      0x01000000
#define FSOT_CHARACTER  0x10000000
 

Code: Select all

 
        // create the PhysXWorld
        m_PhysXWorld = new FSPhysXWorld();
        m_PhysXWorld->initialize();
        m_PhysXWorld->create(getApp()->getPhysXManager(), this);
        m_PhysXWorld->detectCollisionsBetween(FSOT_CHARACTER, FSOT_TRIGGER);
        m_PhysXWorld->detectCollisionsBetween(FSOT_TRIGGER,FSOT_CHARACTER);
 
you create PhysX objects by filling out a descriptive structure and having the world create it....

Code: Select all

 
            // fill out the descriptor
            IPhysXObjectData data;
            data.userdata = getId();
            if (getMass() >0) data.type = POT_PRIMITIVE_BOX;
            else data.type = POT_PRIMITIVE_PLANE;
            data.position = getPosition();
            data.rotation = getRotation();
            data.scale = getScale();
            data.mass = getMass();
            if (getMass() > 0) data.dynamic = true; else data.dynamic = false;
 
            // set the newly created physx object
            setPhysXObject(getLevel()->getPhysXWorld()->createPhysXObject(data));
 



and then create objects that hold pointers to FSPhysX objects

in my case, I have a base class called FSObject

class FSObject
{

public:
FSPhysXObject* m_PhysXObject;
}


and i can manipulate as needed from there.
for example :

Code: Select all

 
    void FSObject::preFrame(const float &elapsedtime)
    {
        if (getPhysXObject()) getPhysXObject()->preFrame(elapsedtime);
 
        if ((getPhysXObject()) && (getPrimarySceneNode()))
        {
            m_Rotation = getPhysXObject()->getRotation();
            m_Position = getPhysXObject()->getPosition();
        setPrimarySceneNodePositionAndRotation(getPosition(), getRotation());
        }
 


i will post the code below but will parse it out so it is a little easier to see...


reminder :
create manager, create world (it will use manager to create), and use world to create obejcts.
keep track of the objects and do whatever you need to with them.
Last edited by Seven on Thu Oct 18, 2018 9:06 pm, edited 2 times in total.
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

somewhere you will need to include these items ( I do it in FSUtils.h )

Code: Select all

 
#include "PxPhysicsAPI.h"
#pragma comment(lib, "PhysX3CHECKED_x86.lib")   
#pragma comment(lib, "PhysX3CommonCHECKED_x86.lib") 
#pragma comment(lib, "PhysX3ExtensionsCHECKED.lib")
#pragma comment(lib, "PhysX3CookingCHECKED_x86.lib")
#pragma comment(lib,"PhysX3CharacterKinematicCHECKED_x86.lib")
#pragma comment(lib, "PsFastXmlCHECKED_x86.lib")    
#pragma comment(lib, "PxFoundationCHECKED_x86.lib") 
#pragma comment(lib, "PxPvdSDKCHECKED_x86.lib") 
#pragma comment(lib, "PxTaskCHECKED_x86.lib")
 
FSPhysX.h

Code: Select all

 
#pragma once
 
// include the needed header files
#include "FSUtils.h"
#include "PxSceneDesc.h"
#include "FSMessageManager.h"
#include "_FSDefines.h"
 
// define this for pvd use
// #define FS_USE_PVD
 
namespace FS
{
    // forward class declaration
    typedef class FSPhysXObject FSPhysXObject;
    typedef class FSLevel FSLevel;
 
    struct FSInContact
    {
        FSMT type;
        int obj1;
        int obj2;
    };
    struct FSFilterData
    {
        long type1;
        long type2;
    };
 
    enum IPhysXObjectType
    {
        POT_AUTO_DETECT,
        POT_PRIMITIVE_BOX,
        POT_PRIMITIVE_SPHERE,
        POT_PRIMITIVE_CONE,
        POT_PRIMITIVE_CAPSULE,
        POT_PRIMITIVE_CYLINDER,
        POT_PRIMITIVE_CHAMFERCYLINDER,
        POT_PRIMITIVE_PLANE,
        POT_CONVEXHULL,
        POT_TREE,
        POT_TERRAIN,
        POT_CHARACTER,
        POT_CHARACTER2,
        POT_TRIGGER,
        POT_MULTISHAPE,
        POT_DYNAMIC_TREE
    };
 
    struct IPhysXObjectData
    {
        IPhysXObjectData() : type(POT_AUTO_DETECT), objecttype(0), node(0), mesh(0),
            position(vector3df(0, 0, 0)), rotation(vector3df(0, 0, 0)), scale(vector3df(1, 1, 1)),
            radius(1), mass(0), gravity(false), linearDamping(0), angularDamping(0.5),
            bboffset(vector3df(0, 0, 0)), plane(1), normal(vector3df(0, 1, 0)), istrigger(0), frozen(0),
            userdata(0), version(1), dynamic(true) {}
        IPhysXObjectType type;
        long objecttype;
        ISceneNode* node;
        IMesh* mesh;
        vector3df position;
        vector3df rotation;
        vector3df scale;
        float radius;
        float mass;
        bool gravity;
        float linearDamping;
        float angularDamping;
        vector3df bboffset;
        float plane;
        vector3df normal;
        bool istrigger;
        bool frozen;
        int userdata;
        int version;
        bool dynamic;
    };
 
    class FSPhysXManager
    {
    public:
        FSPhysXManager()    { /* do nothing */ }
        ~FSPhysXManager()   { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(IrrlichtDevice* device, IVideoDriver* driver);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        // default physix material
        PxMaterial* m_DefaultMaterial;
 
        IrrlichtDevice* m_Device;
        IrrlichtDevice* getDevice() { return m_Device; }
        IVideoDriver* m_Driver;
        IVideoDriver*  getDriver() { return m_Driver; }
 
        PxPhysics* m_PhysXSDK;
        PxPhysics* getPhysXSDK() { return m_PhysXSDK; }
 
        PxFoundation* m_Foundation;
        PxFoundation* getFoundation() { return m_Foundation; }
 
        PxDefaultErrorCallback m_DefaultErrorCallback;
        PxDefaultAllocator m_DefaultAllocator;
 
        PxCooking* m_Cooking;
        PxCooking* getCooking() { return m_Cooking; }
    private:
        bool createPhysX();
        void destroyPhysX();
        void connectPVD();
    };
 
    class FSPhysXWorld : public PxSimulationEventCallback, public PxQueryFilterCallback
    {
    public:
        vector3df m_Start;
        vector3df m_End;
        void drawLine();
 
        FSPhysXWorld()  { /* do nothing */ }
        ~FSPhysXWorld() { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXManager* manager, FSLevel* level);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        // let the class do whatever it does each frame
        virtual void preFrame(const float &elapsedtime);
        virtual void frame(const float &elapsedtime);
        virtual void postFrame(const float &elapsedtime);
 
        virtual void onTrigger(PxTriggerPair* pairs, PxU32 count);
        virtual void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) {}
        virtual void onWake(PxActor** actors, PxU32 count) {}
        virtual void onSleep(PxActor** actors, PxU32 count) {};
        virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs);
 
        virtual PxQueryHitType::Enum preFilter(
            const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags)
        {
            return PxQueryHitType::eBLOCK;
        }
        virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit)
        {
            return PxQueryHitType::eBLOCK;
        }
 
        virtual void onAdvance(const physx::PxRigidBody *const *, const physx::PxTransform *, const physx::PxU32)
        {
        }
 
        // render the physx world in 3d lines
        void renderDebugInfo();
 
        // unsafe methods for getting irrlicht pointers
        IrrlichtDevice*     getDevice();
        IVideoDriver*       getDriver();
 
        // class variables with setters and getters
        FSPhysXManager* m_PhysXManager;
        FSPhysXManager* getPhysXManager() { return m_PhysXManager; }
        PxScene* m_Scene;
        PxScene* getScene() { return m_Scene; }
        PxControllerManager* m_ControllerManager;
        PxControllerManager* getControllerManager() { return m_ControllerManager; }
        
        array<FSInContact> m_ContactList;
        bool inContactList(int id, int id2)
        {
            for (u32 i = 0; i < m_ContactList.size(); i++)
            {
                if ((m_ContactList[i].obj1 == id) && (m_ContactList[i].obj2 == id2)) return true;
                if ((m_ContactList[i].obj2 == id) && (m_ContactList[i].obj1 == id2)) return true;
            }
            return false;
        }
        void removeFromContactList(int id, int id2)
        {
            if (m_ContactList.empty()) return;
            u32 i = 0;
            while (i<=m_ContactList.size())
            {
                if ((m_ContactList[i].obj1 == id) && (m_ContactList[i].obj2 == id2)) m_ContactList.erase(i);
                if ((m_ContactList[i].obj2 == id) && (m_ContactList[i].obj1 == id2)) m_ContactList.erase(i);
                i++;
            }
        }
        void addToContactList(int id, int id2, FSMT type)
        {
            FSInContact c;
            c.obj1 = id;
            c.obj2 = id2;
            c.type = type;
            m_ContactList.push_back(c);
        }
        void removeAllContactInstances(int id)
        {
            for (u32 i = 0; i < m_ContactList.size(); i++)
            {
                if (m_ContactList[i].obj1 == id) m_ContactList.erase(i);
                else if (m_ContactList[i].obj2 == id) m_ContactList.erase(i);
            }
        }
 
        list<FSFilterData*> m_CollisionInfo;
        void removeAllCollisionTypes();
        void detectCollisionsBetween(long o1, long o2);
        bool canCollide(long obj1, long obj2);
 
 
        bool m_RenderDebugInfo;
        void setRenderDebugInfo(bool value) { m_RenderDebugInfo = value; }
        bool getRenderDebugInfo() { return m_RenderDebugInfo; }
        bool m_ResolvePhysX;
        bool getResolvePhysX() { return m_ResolvePhysX; }
        void setResolvePhysX(bool value) { m_ResolvePhysX = value; }
 
        FSLevel* m_Level;
        FSLevel* getLevel() { return m_Level; }
 
        FSPhysXObject* createPhysXObject(const IPhysXObjectData &data);
 
        FSPhysXObject* createCapsuleObject(const IPhysXObjectData &data);
        FSPhysXObject* createCubeObject(const IPhysXObjectData &data);
        FSPhysXObject* createPlaneObject(const IPhysXObjectData &data);
        FSPhysXObject* createTerrainObject(const IPhysXObjectData &data);
        FSPhysXObject* createCharacterObject(const IPhysXObjectData &data);
 
        FSPhysXObject* createTreeObject(const IPhysXObjectData &data);
        FSPhysXObject* createStaticTreeObject(const IPhysXObjectData &data);
        FSPhysXObject* createDynamicTreeObject(const IPhysXObjectData &data);
        PxRigidStatic* createStaticTreeChunk(IPhysXObjectData data, int index);
        PxRigidDynamic* createDynamicTreeChunk(IPhysXObjectData data, int index);
 
        int pickClosestObject(int x, int y, ISceneCollisionManager* collMan, ICameraSceneNode* cam, long ot);
    };
 
    class FSPhysXObject
    {
    public:
        FSPhysXObject() { /* do nothing */ }
        ~FSPhysXObject()    { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize() { m_World = 0; };
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXWorld* world) { m_World = world;  return true; };
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup() { m_World = 0;  return false; };
 
        // let the class do whatever it does each frame
        virtual void preFrame(const float &elapsedtime)     {};
        virtual void frame(const float &elapsedtime)        {};
        virtual void postFrame(const float &elapsedtime)    {};
 
        virtual vector3df getPosition()                                     { return vector3df(0, 0, 0); }
        virtual vector3df getRotation()                                     { return vector3df(0, 0, 0); }
        virtual void setPosition(vector3df pos)                             {                                                       }
        virtual void setRotation(vector3df rot)                             {                                                       }
        virtual void getPositionAndRotation(vector3df &pos, vector3df &rot) { pos = vector3df(0, 0, 0); rot = vector3df(0, 0, 0); }
 
        virtual void setFreeze(bool value)                  {};
        virtual void setMass(float value)                   {};
        virtual float getMass()                             { return 0; };
        virtual void setLinearDamping(float value)          {};
        virtual void setAngularDamping(float value)         {};
        virtual void rotate(vector3df rotOffset)            { setRotation(getRotation() + rotOffset); }
 
        // add a force to the object
        virtual void addForce(vector3df dir, float magnitude) {}
 
        virtual vector3df getIn()       { return vector3df(0, 0, 0); }
        virtual vector3df getLeft()     { return vector3df(0, 0, 0); }
        virtual vector3df getUp()       { return vector3df(0, 0, 0); }
 
        // attach this to an object
        virtual void setUserData(int id) {}
        virtual void setObjectType(long t) {}
 
        FSPhysXWorld* m_World;
        FSPhysXWorld* getWorld() { return m_World; }
 
    };
 
    class FSPhysXObject_RigidDynamic : public FSPhysXObject
    {
    public:
        FSPhysXObject_RigidDynamic()    { /* do nothing */ }
        ~FSPhysXObject_RigidDynamic()   { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXWorld* world);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        virtual vector3df getPosition();
        virtual vector3df getRotation();
        virtual void setPosition(vector3df pos);
        virtual void setRotation(vector3df rot);
        virtual void getPositionAndRotation(vector3df &pos, vector3df &rot);
 
        virtual void setFreeze(bool value);
        virtual void setMass(float value);
        virtual float getMass();
        virtual void setLinearDamping(float value);
        virtual void setAngularDamping(float value);
        virtual void rotate(vector3df rotOffset);
 
        // add a force to the object
        virtual void addForce(vector3df dir, float magnitude);
 
        // attach this to an object
        virtual void setUserData(int id);
        virtual void setObjectType(long t);
 
        PxRigidDynamic* m_Actor;
        void setActor(PxRigidDynamic* a) { m_Actor = a; };
        PxRigidDynamic* getActor() { return m_Actor; }
    };
 
    class FSPhysXObject_RigidStatic : public FSPhysXObject
    {
    public:
        FSPhysXObject_RigidStatic()     { /* do nothing */ }
        ~FSPhysXObject_RigidStatic()    { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXWorld* world);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        virtual vector3df getPosition();
        virtual vector3df getRotation();
        virtual void setPosition(vector3df pos);
        virtual void setRotation(vector3df rot);
        virtual void getPositionAndRotation(vector3df &pos, vector3df &rot);
 
        virtual void rotate(vector3df rotOffset);
 
        // attach this to an object
        virtual void setUserData(int id);
        virtual void setObjectType(long t);
 
        PxRigidStatic* m_Actor;
        PxRigidStatic* getActor() { return m_Actor; }
        void setActor(PxRigidStatic* a) { m_Actor = a; }
    };
 
#define MAX_ACTORS 100
    class FSPhysXObject_StaticTree : public FSPhysXObject_RigidStatic
    {
    public:
        FSPhysXObject_StaticTree() { /* do nothing */ }
        ~FSPhysXObject_StaticTree() { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXWorld* world);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        virtual void setPosition(vector3df pos);
        virtual void setRotation(vector3df rot);
 
        virtual void addActor(PxRigidStatic* actor);
        PxRigidStatic* m_Actors[MAX_ACTORS];
 
        // attach this to an object
        virtual void setUserData(int id);
        virtual void setObjectType(long t);
    };
 
    class FSPhysXObject_DynamicTree : public FSPhysXObject_RigidDynamic
    {
    public:
        FSPhysXObject_DynamicTree() { /* do nothing */ }
        ~FSPhysXObject_DynamicTree() { /* do nothing */ }
 
        // initialize the class. 
        // Set all variables to a known value
        virtual void initialize();
 
        // dual creation allows for better error handling. 
        // All class variables are valid after this call
        // return false on failure
        virtual bool create(FSPhysXWorld* world);
 
        // cleanup whatever memory mess we made.
        // all class variables are made invalid
        // always return false from a cleanup function
        virtual bool cleanup();
 
        virtual void setPosition(vector3df pos);
        virtual void setRotation(vector3df rot);
 
        virtual void addActor(PxRigidDynamic* actor);
        PxRigidDynamic* m_Actors[MAX_ACTORS];
 
        // attach this to an object
        virtual void setUserData(int id);
        virtual void setObjectType(long t);
    };
 
    class ControllerHitReport : public PxUserControllerHitReport
    {
    public:
        virtual void onControllerHit(const PxControllersHit& hit)
        {
            
        }
 
        virtual void onObstacleHit(const PxControllerObstacleHit& hit)
        {
        }
 
        virtual void onShapeHit(const PxControllerShapeHit& hit)
        {
        }
 
    };
 
    extern ControllerHitReport gControllerHitReport;
 
    class FSPhysXObject_Character : public FSPhysXObject, public PxControllerFilterCallback
    {
    public:
        FSPhysXObject_Character(void)           {}
        virtual ~FSPhysXObject_Character(void)  {}
 
        virtual void initialize();
        virtual bool create(FSPhysXWorld* world, IPhysXObjectData data);
        virtual bool cleanup();
 
        virtual void frame(const float &elapsedtime);
 
 
        virtual bool filter(const PxController& a, const PxController& b);
 
        virtual void setPosition(vector3df pos);
        virtual vector3df getPosition();
 
        virtual void drawDebugInfo(SColor color);
        virtual void setFreeze(bool value);
        virtual void setMass(float value);
        virtual float getMass();
        virtual void setLinearDamping(float value);
        virtual void setAngularDamping(float value);
 
        vector3df m_TotalForce;
        void setTotalForce(vector3df f) { m_TotalForce = f; }
        vector3df getTotalForce() { return m_TotalForce; }
        virtual void addForce(vector3df dir, float force);
 
        virtual PxActor*    getActor()  { if (m_Controller) return m_Controller->getActor(); else return NULL; }
        PxU32 moveCharacter(const PxVec3& dispVector, PxF32 elapsedTime, PxU32 collisionGroups);
 
        PxController* getController() { return m_Controller; }
        PxController* m_Controller;
 
        virtual void jump();
        bool getJumping() { return m_Jumping; }
        bool m_JumpFinished;
        bool getJumpFinished() { return m_JumpFinished; }
 
        PxF32 getHeight(PxF32 elapsedTime);
 
        virtual void crouch(bool v);
        bool getCrouching() { return m_Crouching; }
 
        // attach this to an object
        virtual void setUserData(int id);
        virtual void setObjectType(long t);
 
    private:
        bool    m_Jumping;
        bool    m_Crouching;
        PxF32   m_JumpTime;
        PxF32   m_MaxJumpTime;
        void stopJumping();
//      void inJump();
    };
 
 
    void setGlobalPhysXWorld(FSPhysXWorld* w);
 
} // end namespace
 
 
Last edited by Seven on Thu Oct 18, 2018 9:03 pm, edited 1 time in total.
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

FSPhysXManager.cpp

Code: Select all

 
 
#include "FSUtils.h"
#include "FSPhysX.h"
#include "FSLogger.h"
 
namespace FS
{
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXManager::initialize()
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::initialize()");
 
        m_Device = 0;
        m_Driver = 0;
        m_PhysXSDK = 0;
        m_Foundation = 0;
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXManager::create(IrrlichtDevice* device, IVideoDriver* driver)
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::create()");
 
        // remember these
        m_Device = device;
        m_Driver = driver;
        
        // initialize the physx sdk
        if (!createPhysX()) { FS_LOG(FSL_DEBUG, "ERROR unable to create PhysX sdk"); return false;  }
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXManager::cleanup()
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::cleanup()");
 
        // shutdown the physx sdk
        destroyPhysX();
 
        // forget these
        m_Device = 0;
        m_Driver = 0;
 
        // always return false from a cleanup function
        return false;
    }
 
    // initialize the physx sdk objects
    bool FSPhysXManager::createPhysX()
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::createPhysX()");
 
        // Create the physX foundation
        //m_Foundation = PxCreateFoundation(PX_PHYSICS_VERSION, m_DefaultAllocatorCallback, m_DefaultErrorCallback);
        m_Foundation = PxCreateFoundation(PX_FOUNDATION_VERSION, m_DefaultAllocator, m_DefaultErrorCallback);
 
        
        // verify that we succeeded
        if (!m_Foundation) { FS_LOG(FSL_ERROR, "ERROR physx Foundation is not initialized properly"); return false; }
 
        // create the PhysX SDK
        m_PhysXSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *m_Foundation, PxTolerancesScale());
 
        // verify that we succeeded
        if (!m_PhysXSDK) { FS_LOG(FSL_ERROR, "ERROR physx sdk is not initialized properly"); return false; }
 
        // create the default material
        getPhysXSDK()->createMaterial(0.5f, 0.5f, 0.5f);
        getPhysXSDK()->getMaterials(&m_DefaultMaterial, 1);
        m_DefaultMaterial->setRestitution(0);
        m_DefaultMaterial->setStaticFriction(0.5f);
        m_DefaultMaterial->setDynamicFriction(0.5f);
 
        PxTolerancesScale scale;
        PxCookingParams params(scale);
        params.meshWeldTolerance = 0.001f;
        params.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES );
        m_Cooking = PxCreateCooking(PX_PHYSICS_VERSION, *m_Foundation, params);
        if (!m_Cooking) { FS_LOG(FSL_ERROR, "PxCreateCooking failed!"); return false; }
 
        // connect to the visualization
        connectPVD();
 
        // everything went fine
        return true;
    }
 
    // shutdown PhysX
    void FSPhysXManager::destroyPhysX()
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::destroyPhysX()");
        if (m_Cooking)      { m_Cooking->release(); m_Cooking = 0; }
        if (m_PhysXSDK) { m_PhysXSDK->release(); m_PhysXSDK = 0; }
        if (m_Foundation)   { m_Foundation->release(); m_Foundation = 0; }
    }
 
    void FSPhysXManager::connectPVD()                   //Function for the visualization of PhysX simulation (Optional and 'Debug' mode only) 
    {
        FS_LOG(FSL_DEBUG, "FSPhysXManager::connectPVD()");
 
#if(0)
        // check if PvdConnection manager is available on this platform
        if (getPhysXSDK()->getPvdConnectionManager() == NULL)
        {
            // log this event
            FS_LOG(FSL_DEBUG, "no pvd connection found.....");
 
            // bail 
            return;
        }
 
        // setup connection parameters
        const char*     pvd_host_ip = "127.0.0.1";  // IP of the PC which is running PVD
        int             port = 5425;         // TCP port to connect to, where PVD is listening
        unsigned int    timeout = 100;          // timeout in milliseconds to wait for PVD to respond,
        // consoles and remote PFS need a higher timeout.
        PxVisualDebuggerConnectionFlags connectionFlags = PxVisualDebuggerExt::getAllConnectionFlags();
 
        // and now try to connect
        debugger::comm::PvdConnection* theConnection = PxVisualDebuggerExt::createConnection(getPhysXSDK()->getPvdConnectionManager(),
            pvd_host_ip, port, timeout, connectionFlags);
#endif
    }
 
} // end namespace
 
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

FSPhysXWorld.cpp

Code: Select all

 
#include "FSUtils.h"
#include "FSPhysX.h"
#include "FSLogger.h"
#include "FSLevel.h"
#include "FSObjectFactory.h"
#include "FSMessageManager.h"
#include "FSObject.h"
namespace FS
{
    // need to fix this. how to send world* to simulationfilter????
    // for now, this is set at FSLevel::load() and FSLevel::unload()
    FSPhysXWorld* gPhysXWorld = 0;
    void setGlobalPhysXWorld(FSPhysXWorld* w) { gPhysXWorld = w; }
 
    // filter the collisions. only process the collisions we care about
    PxFilterFlags SimulationFilterShader(
        PxFilterObjectAttributes attributes0, PxFilterData filterData0,
        PxFilterObjectAttributes attributes1, PxFilterData filterData1,
        PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
    {
        // let triggers through
        if (PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
        {
            pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
            return PxFilterFlag::eDEFAULT;
        }
 
        // generate contacts for all that were not filtered above
        pairFlags = PxPairFlag::eCONTACT_DEFAULT;
 
        // if the world is valid (how did we get here if it isnt?)
        if (gPhysXWorld)
        {
            if (
                (pairFlags & PxPairFlag::eSOLVE_CONTACT) ||
                (pairFlags & PxPairFlag::eMODIFY_CONTACTS) ||
                (pairFlags & PxPairFlag::eNOTIFY_TOUCH_LOST) ||
 
                (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND) ||
                (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS) ||
                (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST) ||
 
                (pairFlags & PxPairFlag::eNOTIFY_CONTACT_POINTS) ||
                (pairFlags & PxPairFlag::eDETECT_DISCRETE_CONTACT) ||
 
                (pairFlags & PxPairFlag::ePRE_SOLVER_VELOCITY) ||
                (pairFlags & PxPairFlag::ePOST_SOLVER_VELOCITY) ||
 
                (pairFlags & PxPairFlag::eCONTACT_EVENT_POSE)
                )
            {
                // could handle all of these independently if we wanted
                // let the collision occur
                return PxFilterFlag::eDEFAULT;
            }
            else
            {
                // the collision flags
                //(pairFlags & PxPairFlag::eNOTIFY_TOUCH_FOUND)
                //(pairFlags & PxPairFlag::eNOTIFY_TOUCH_PERSISTS)
                //(pairFlags & PxPairFlag::eNOTIFY_TOUCH_CCD)
                //(pairFlags & PxPairFlag::eNOTIFY_CCD_CONTACT)
 
                // trigger the contact callback if the OBJECT_TYPES of the two objects are supposed to report contact with each other
                if (gPhysXWorld->canCollide(filterData0.word0, filterData1.word0)) pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
            }
        }
 
        // let the collision occur
        return PxFilterFlag::eDEFAULT;
    }
 
    // simple function. off of irrlicht forums somewhere
    PxQuat buildPxQuat(vector3df pos, vector3df rot)
    {
        matrix4 irrM;
        irrM.setTranslation(pos);
        irrM.setRotationDegrees(rot);
        quaternion q(irrM);
        return PxQuat(q.X, q.Y, q.Z, q.W);
    }
 
    /*
    simple wrapper for physx scene
    */
 
    // unsafe methods for getting irrlicht pointers
    IrrlichtDevice*     FSPhysXWorld::getDevice()       { return getPhysXManager()->getDevice(); }
    IVideoDriver*       FSPhysXWorld::getDriver()       { return getPhysXManager()->getDriver(); }
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXWorld::initialize()
    {
        // log this event
        FS_LOG(FSL_DEBUG, "FSPhysXWorld::initialize()");
 
        // set all variables to a known value
        m_PhysXManager = 0;
        m_Level = 0;
        m_Scene = 0;
        m_ControllerManager = 0;
        setResolvePhysX(true);
 
        // default to not showing the debug renderings
        setRenderDebugInfo(false);
 
        // clear the collision tests structures
        m_CollisionInfo.clear();
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXWorld::create(FSPhysXManager* physx3, FSLevel* level)
    {
        // log this event
        FS_LOG(FSL_DEBUG, "FSPhysXWorld::create()");
 
        // remember this
        m_PhysXManager = physx3;
        m_Level = level;
 
        //Create the scene
        PxSceneDesc sceneDesc(getPhysXManager()->getPhysXSDK()->getTolerancesScale());  //Descriptor class for scenes 
        sceneDesc.sanityBounds.minimum.x = -PX_MAX_BOUNDS_EXTENTS;
        sceneDesc.sanityBounds.minimum.y = -PX_MAX_BOUNDS_EXTENTS;
        sceneDesc.sanityBounds.minimum.z = -PX_MAX_BOUNDS_EXTENTS;
        sceneDesc.sanityBounds.maximum.x = PX_MAX_BOUNDS_EXTENTS;
        sceneDesc.sanityBounds.maximum.y = PX_MAX_BOUNDS_EXTENTS;
        sceneDesc.sanityBounds.maximum.z = PX_MAX_BOUNDS_EXTENTS;
 
        sceneDesc.gravity = PxVec3(0.0f, -132.0f, 0.0f);                //Setting gravity
        sceneDesc.cpuDispatcher = PxDefaultCpuDispatcherCreate(1);  //Creates default CPU dispatcher for the scene
        sceneDesc.filterShader = SimulationFilterShader;    //Creates default collision filter shader for the scene
 
        sceneDesc.flags |= PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS | PxSceneFlag::eENABLE_KINEMATIC_PAIRS;
 
        //Creates a scene 
        m_Scene = getPhysXManager()->getPhysXSDK()->createScene(sceneDesc);
 
        // send the callbacks to us
        m_Scene->setSimulationEventCallback(this);
 
        // Set the debug visualization parameters
        getScene()->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1);
        getScene()->setVisualizationParameter(PxVisualizationParameter::eACTOR_AXES, 1);
        getScene()->setVisualizationParameter(PxVisualizationParameter::eBODY_ANG_VELOCITY, 1);
        getScene()->setVisualizationParameter(PxVisualizationParameter::eBODY_AXES, 1);
        getScene()->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1);
 
        // create the character controller manager
        m_ControllerManager = PxCreateControllerManager(*m_Scene);
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXWorld::cleanup()
    {
        // log this event
        FS_LOG(FSL_DEBUG, "FSPhysXWorld::cleanup()");
 
        // cleanup the collision types
        removeAllCollisionTypes();
 
        // safely release the controller manager
        if (m_ControllerManager) { m_ControllerManager->release(); m_ControllerManager = 0; }
 
        // safely release the scene
        if (m_Scene) { m_Scene->release(); m_Scene = 0; }
 
        // forget this
        m_PhysXManager = 0;
        m_Level = 0;
 
        // always return false from a cleanup function
        return false;
    }
 
    // let the class do whatever it does each frame
    void FSPhysXWorld::preFrame(const float &elapsedtime)
    {
        // if we are resolving the simulation
        if (getResolvePhysX())
        {
            //Advances the simulation by elapsedtime
            if (getScene()) getScene()->simulate(elapsedtime);
 
            //Block until the simulation run is completed
            if (getScene()) getScene()->fetchResults(true);
 
        }
    }
 
    // let the class do whatever it does each frame
    void FSPhysXWorld::frame(const float &elapsedtime)
    {
        for (u32 i = 0; i < m_ContactList.size(); i++)
        {
            // hmmmm, do we want trigger messages or collision messages??
            getLevel()->getObjectFactory()->getMessageManager()->addMessage(m_ContactList[i].type, MSG_NULL, m_ContactList[i].obj2, m_ContactList[i].obj1, 0, 0, "");
            getLevel()->getObjectFactory()->getMessageManager()->addMessage(m_ContactList[i].type, MSG_NULL, m_ContactList[i].obj1, m_ContactList[i].obj2, 0, 0, "");
            if (m_ContactList[i].type == MESSAGE_TRIGGER_ENTER)  m_ContactList[i].type = MESSAGE_TRIGGER_CONTACT;
        }
    }
 
    // let the class do whatever it does each frame
    void FSPhysXWorld::postFrame(const float &elapsedtime)
    {
    }
 
    void FSPhysXWorld::removeAllCollisionTypes()
    {
        // runt hrought he list and remove them all
        if (!m_CollisionInfo.empty())
        {
            list<FSFilterData*>::Iterator it;
            for (it = m_CollisionInfo.begin(); it != m_CollisionInfo.end();)
            {
                delete((*it));
                it = m_CollisionInfo.erase(it);
            }
        }
        m_CollisionInfo.clear();
    }
 
    // maintains the list of collisions we will react to
    void FSPhysXWorld::detectCollisionsBetween(long o1, long o2)
    {
        FSFilterData* filterData = new FSFilterData();
        filterData->type1 = o1;
        filterData->type2 = o2;
        m_CollisionInfo.push_back(filterData);
    }
 
    // check to see if we care about this collision based on the two collision types
    bool FSPhysXWorld::canCollide(long obj1, long obj2)
    {
        if (!m_CollisionInfo.empty())
        {
            list<FSFilterData*>::ConstIterator it;
            for (it = m_CollisionInfo.begin(); it != m_CollisionInfo.end();)
            {
                if (((*it)->type1 == obj1) && ((*it)->type2 == obj2)) return true;
                if (((*it)->type1 == obj2) && ((*it)->type2 == obj1)) return true;
                it++;
            }
        }
 
        // we did not find the collision pair so we must not care about this one
        return false;
    }
 
    // called by PhysX when a trigger object detects a collision
    void FSPhysXWorld::onTrigger(PxTriggerPair* pairs, PxU32 count)
    {
        for (PxU32 i = 0; i < count; i++)
        {
            // ignore pairs when shapes have been deleted
            if (pairs[i].flags & (PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER | PxTriggerPairFlag::eREMOVED_SHAPE_OTHER))
            {
                FS_LOG(FSL_DEBUG, "deleted shape trigger - no contact message sent");
                continue;
            }
 
            // get the id's of the two colliding objects
            int target = (int)pairs[i].otherShape->getActor()->userData;
            int me = (int)pairs[i].triggerShape->getActor()->userData;
 
            // if the level is valid
            if (getLevel())
            {
                if (pairs[i].status == PxPairFlag::eNOTIFY_TOUCH_FOUND)
                {
                    if (!inContactList(me, target))
                    {
                        //printf("adding to contact list %d %d\n", target, me);
                        addToContactList(me, target, MESSAGE_TRIGGER_ENTER);
                    }
                }
                if (pairs[i].status == PxPairFlag::eNOTIFY_TOUCH_LOST)
                {
                    // currently there is no collision lost message so send trigger_exit isntead
                    // maybe we need collision lost instead?
                    getLevel()->getObjectFactory()->getMessageManager()->addMessage(MESSAGE_TRIGGER_EXIT, MSG_NULL, target, me, 0, 0, "");
                    //printf("removing to contact list %d %d\n", target, me);
                    removeFromContactList(target, me);
                    removeFromContactList(me,target);
                }
            }
 
        }
    }
 
    // called by PhysX when two objects collide (if it passed out checkcollisions function)
    void FSPhysXWorld::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
    {
        for (PxU32 i = 0; i < nbPairs; i++)
        {
            const PxContactPair& cp = pairs[i];
 
            // if the event type is touch_found
            if (
                (cp.events & PxPairFlag::eNOTIFY_TOUCH_FOUND) || 
                (cp.events & PxPairFlag::eNOTIFY_TOUCH_PERSISTS) ||
                (cp.events & PxPairFlag::eNOTIFY_TOUCH_CCD) ||
                (cp.events & PxPairFlag::eDETECT_CCD_CONTACT)
                )
            {
                if (getLevel())
                {
                    // send the collision message to the level to broadcast through the objects
                    getLevel()->getObjectFactory()->getMessageManager()->addMessage(MESSAGE_COLLISION, MSG_NULL, (int)pairHeader.actors[0]->userData, (int)pairHeader.actors[1]->userData, 0, 0, "");
                    getLevel()->getObjectFactory()->getMessageManager()->addMessage(MESSAGE_COLLISION, MSG_NULL, (int)pairHeader.actors[1]->userData, (int)pairHeader.actors[0]->userData, 0, 0, "");
                }
            }
        }
    }
 
    int FSPhysXWorld::pickClosestObject(int x, int y, ISceneCollisionManager* collMan, ICameraSceneNode* cam, long ot)
    {
        // if the scene is notvalid then return NULL
        if (!getScene()) return NULL;
 
        position2d<s32> pos(x, y);
        const core::line3d<f32> ln = collMan->getRayFromScreenCoordinates(pos, cam);
 
        PxVec3 start(ln.start.X, ln.start.Y, ln.start.Z);
        vector3df d(ln.getVector());
        d.normalize();
        PxVec3 dir(d.X, d.Y, d.Z);
        PxSceneQueryHit hit;
        const PxSceneQueryFilterData filterData = PxSceneQueryFilterData();
            
        const PxU32 bufferSize = 256;        // [in] size of 'hitBuffer'
        PxRaycastHit hitBuffer[bufferSize];  // [out] User provided buffer for results
        PxRaycastBuffer buf(hitBuffer, bufferSize); // [out] Blocking and touching hits will be stored here
        
 
        m_Start = vector3df(ln.start.X, ln.start.Y, ln.start.Z);
        m_End = vector3df(ln.end.X, ln.end.Y, ln.end.Z);
 
        float distance = 10000000;
        int best = -1;
        getScene()->raycast(start, dir,10000.0f,buf, PxHitFlags(PxHitFlag::eDEFAULT), PxQueryFilterData(),this);
        if (buf.nbTouches > 0)
        {
            for (PxU32 x = 0; x < buf.getNbTouches(); x++)
            {
                FSObject* obj = getLevel()->getObjectPointer((int)buf.touches[x].actor->userData, true);
                if ((obj) &&  ( (ot == FSOT_ALL) || (obj->getObjectType() == ot)) )
                {
                    if (buf.getTouch(x).distance < distance)
                    {
                        distance = buf.getTouch(x).distance;
                        best = x;
                    }
                }
            }
        }
        if (best == -1) return 0;
        return (int)buf.getTouch(best).actor->userData;
    }
 
    void FSPhysXWorld::drawLine()
    {
        IrrlichtDevice* device = getDevice();
        IVideoDriver* driver = getDriver();
 
/*
        video::SMaterial material;
        material.Wireframe = false;
        material.Lighting = false;
        getDriver()->setMaterial(material);
        getDriver()->setTransform(video::ETS_WORLD, core::matrix4());
        SColor colour(255, 255, 0, 255);
        driver->draw3DLine(m_Start, m_End, SColor(255, 255, 255, 255));
*/
    }
 
    void FSPhysXWorld::renderDebugInfo()
    {
        if (!getRenderDebugInfo()) return;
 
        IrrlichtDevice* device = getDevice();
        IVideoDriver* driver = getDriver();
 
        video::SMaterial material;
        material.Wireframe = false;
        material.Lighting = false;
        getDriver()->setMaterial(material);
        getDriver()->setTransform(video::ETS_WORLD, core::matrix4());
        SColor colour(255, 255, 0, 255);
 
        const PxRenderBuffer& data = getScene()->getRenderBuffer();
//      if (data)
        {
            driver->setMaterial(material);
            driver->setTransform(video::ETS_WORLD, core::matrix4());
 
            u32 NbPoints = data.getNbPoints();
            if (NbPoints) {
                // printf("want to draw points\n");
            }
 
            u32 numLines = data.getNbLines();
            if (numLines) {
                video::S3DVertex* pVertList = new video::S3DVertex[numLines * 2];
                u16* pIndexList = new u16[numLines * 2];
                u32 vertIndex = 0;
                u32 indexIndex = 0;
                const PxDebugLine* lines = data.getLines();
                while (numLines--) {
                    pIndexList[indexIndex++] = vertIndex;
                    pVertList[vertIndex].Pos.X = lines->pos0.x;
                    pVertList[vertIndex].Pos.Y = lines->pos0.y;
                    pVertList[vertIndex].Pos.Z = lines->pos0.z;
                    pVertList[vertIndex].Color = colour;
                    vertIndex++;
 
                    pIndexList[indexIndex++] = vertIndex;
                    pVertList[vertIndex].Pos.X = lines->pos1.x;
                    pVertList[vertIndex].Pos.Y = lines->pos1.y;
                    pVertList[vertIndex].Pos.Z = lines->pos1.z;
                    pVertList[vertIndex].Color = colour;
                    vertIndex++;
 
 
                    if (indexIndex >= 65530) { // 66536 index limit so before we reach it fire off a render and reset to zero
                        driver->drawVertexPrimitiveList(pVertList, vertIndex, pIndexList, indexIndex / 2, video::EVT_STANDARD, scene::EPT_LINES, video::EIT_16BIT);
                        indexIndex = 0;
                        vertIndex = 0;
                    }
 
                    lines++;
                }
 
                driver->drawVertexPrimitiveList(pVertList, vertIndex, pIndexList, indexIndex / 2, video::EVT_STANDARD, scene::EPT_LINES, video::EIT_16BIT);
 
                delete[] pVertList;
                delete[] pIndexList;
            }
 
            u32 numTris = data.getNbTriangles();
            if (numTris) {
                video::S3DVertex* pVertList = new video::S3DVertex[numTris * 3];
                u16* pIndexList = new u16[numTris * 3];
                u32 vertIndex = 0;
                u32 indexIndex = 0;
                const PxDebugTriangle* triangles = data.getTriangles();
                while (numTris--) {
                    pIndexList[indexIndex++] = vertIndex;
                    pVertList[vertIndex].Pos.X = triangles->pos0.x;
                    pVertList[vertIndex].Pos.Y = triangles->pos0.y;
                    pVertList[vertIndex].Pos.Z = triangles->pos0.z;
                    pVertList[vertIndex].Color = colour;
                    vertIndex++;
 
                    pIndexList[indexIndex++] = vertIndex;
                    pVertList[vertIndex].Pos.X = triangles->pos1.x;
                    pVertList[vertIndex].Pos.Y = triangles->pos1.y;
                    pVertList[vertIndex].Pos.Z = triangles->pos1.z;
                    pVertList[vertIndex].Color = colour;
                    vertIndex++;
 
                    pIndexList[indexIndex++] = vertIndex;
                    pVertList[vertIndex].Pos.X = triangles->pos2.x;
                    pVertList[vertIndex].Pos.Y = triangles->pos2.y;
                    pVertList[vertIndex].Pos.Z = triangles->pos2.z;
                    pVertList[vertIndex].Color = colour;
                    vertIndex++;
 
                    triangles++;
                }
                numTris = data.getNbTriangles();
 
                driver->drawIndexedTriangleList(pVertList, numTris * 3, pIndexList, numTris);
                delete[] pVertList;
                delete[] pIndexList;
            }
        }
    }
 
    FSPhysXObject* FSPhysXWorld::createPhysXObject(const IPhysXObjectData &data)
    {
        switch (data.type)
        {
            case POT_PRIMITIVE_CAPSULE  : return createCapsuleObject(data);     break;
            case POT_PRIMITIVE_BOX      : return createCubeObject(data);        break;
            case POT_PRIMITIVE_PLANE    : return createCubeObject(data);        break;
            case POT_TRIGGER            : return createCubeObject(data);        break;
            case POT_TREE               :
            case POT_MULTISHAPE         : return createTreeObject(data);        break;
            case POT_TERRAIN            : return createTerrainObject(data);     break;
            case POT_CHARACTER: return createCharacterObject(data); break;
            case POT_DYNAMIC_TREE: return createDynamicTreeObject(data);    break;
        }
 
        // undefined object type
        return NULL;
    }
 
    FSPhysXObject* FSPhysXWorld::createCapsuleObject(const IPhysXObjectData &data)
    {
        vector3df scale = data.scale + data.bboffset;
        scale.X /= 2;
 
        vector3df pos = data.position;
//      if (data.bboffset.Y != 0) pos.Y += data.bboffset.Y / 2;
 
        if (data.dynamic)
        {
            FSPhysXObject_RigidDynamic* obj = new FSPhysXObject_RigidDynamic();
            obj->initialize();
            obj->create(this);
 
            PxRigidDynamic* actor = getPhysXManager()->getPhysXSDK()->createRigidDynamic(PxTransform(pos.X, pos.Y, pos.Z));
            if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addCapsuleActor() call"); return NULL; }
            actor->setMass(data.mass);
            actor->setAngularDamping(1.0f);
            actor->setLinearDamping(1.0f);
            actor->setLinearVelocity(PxVec3(0, 0, 0));
 
            PxShape* shape = actor->createShape(PxCapsuleGeometry(scale.X, scale.Y), *getPhysXManager()->m_DefaultMaterial);
            if (!shape) { FS_LOG(FSL_DEBUG, "WARNING! shape is not valid in addCapsuleActor() call"); return NULL; }
            
            PxTransform relativePose(PxQuat(PxHalfPi, PxVec3(0, 0, 1)));
            shape->setLocalPose(relativePose);
 
            if (data.istrigger)
            {
                shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
                shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
            }
 
            PxRigidBodyExt::updateMassAndInertia(*actor, PxReal(data.mass));
 
            getScene()->addActor(*actor);
            obj->setActor(actor);
 
            actor->userData = (void*)data.userdata;
            shape->userData = (void*)data.userdata;
 
            obj->setRotation(data.rotation);
            return obj;
        }
        else
        {
            FSPhysXObject_RigidStatic* obj = new FSPhysXObject_RigidStatic();
            obj->initialize();
            obj->create(this);
 
            PxRigidStatic* actor = getPhysXManager()->getPhysXSDK()->createRigidStatic(PxTransform(PxVec3(data.position.X, data.position.Y, data.position.Z), buildPxQuat(data.position, data.rotation)));
            if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addCapsuleActor() call"); return NULL; }
 
            PxShape* shape = actor->createShape(PxCapsuleGeometry(scale.X, scale.Y), *getPhysXManager()->m_DefaultMaterial);
            if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addCapsuleActor() call"); return NULL;    }
 
            PxTransform relativePose(PxQuat(PxHalfPi, PxVec3(0, 0, 1)));
            shape->setLocalPose(relativePose);
 
            if (data.istrigger)
            {
                shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
                shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
            }
 
            getScene()->addActor(*actor);
            obj->setActor(actor);
 
            actor->userData = (void*)data.userdata;
            shape->userData = (void*)data.userdata;
 
            return obj;
        }
        return NULL;
    }
 
    FSPhysXObject* FSPhysXWorld::createCubeObject(const IPhysXObjectData &data)
    {
        vector3df scale = data.scale/2 + data.bboffset;
        vector3df pos = data.position;
        
        if (data.dynamic)
        {
            FSPhysXObject_RigidDynamic* obj = new FSPhysXObject_RigidDynamic();
            obj->initialize();
            obj->create(this);
 
            PxRigidDynamic* actor = getPhysXManager()->getPhysXSDK()->createRigidDynamic(PxTransform(pos.X, pos.Y, pos.Z));
            if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addCubeActor() call"); return NULL; }
            actor->setAngularDamping(1.0f);
            actor->setLinearDamping(1.0f);
            actor->setLinearVelocity(PxVec3(0, 0, 0));
            actor->setMass(data.mass);
 
            PxShape* shape = actor->createShape(PxBoxGeometry(scale.X, scale.Y, scale.Z), *getPhysXManager()->m_DefaultMaterial);
            if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addCubeActor() call"); return NULL; }
            if (data.istrigger)
            {
                shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
                shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
            }
            PxRigidBodyExt::updateMassAndInertia(*actor, PxReal(data.mass));
            
            getScene()->addActor(*actor);
            obj->setActor(actor);
 
            actor->userData = (void*)data.userdata;
            shape->userData = (void*)data.userdata;
 
            obj->setRotation(data.rotation);
            return obj;
        }
        else
        {
            FSPhysXObject_RigidStatic* obj = new FSPhysXObject_RigidStatic();
            obj->initialize();
            obj->create(this);
 
            PxRigidStatic* actor = getPhysXManager()->getPhysXSDK()->createRigidStatic(PxTransform(PxVec3(data.position.X,data.position.Y,data.position.Z),buildPxQuat(data.position,data.rotation)));
            if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addCubeActor() call"); return NULL; }
            
            PxShape* shape = actor->createShape(PxBoxGeometry(scale.X, scale.Y, scale.Z), *getPhysXManager()->m_DefaultMaterial);
            if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addCubeActor() call"); return NULL; }
            if (data.istrigger)
            {
                shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
                shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
            }
 
            getScene()->addActor(*actor);
            obj->setActor(actor);
 
            actor->userData = (void*)data.userdata;
            shape->userData = (void*)data.userdata;
 
            obj->setRotation(data.rotation);
            return obj;
        }
        return NULL;
    }
 
    FSPhysXObject* FSPhysXWorld::createPlaneObject(const IPhysXObjectData &data)
    {
        vector3df scale = data.scale;
        scale /= 2;
 
        FSPhysXObject_RigidStatic* obj = new FSPhysXObject_RigidStatic();
        obj->initialize();
        obj->create(this);
 
        PxRigidStatic* actor = getPhysXManager()->getPhysXSDK()->createRigidStatic(PxTransform(PxVec3(data.position.X, data.position.Y, data.position.Z)));
        if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addCubeActor() call"); return NULL; }
 
        PxShape* shape = actor->createShape(PxBoxGeometry(scale.X, scale.Y, scale.Z), *getPhysXManager()->m_DefaultMaterial);
        if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addCubeActor() call"); return NULL; }
 
        getScene()->addActor(*actor);
        obj->setActor(actor);
 
        actor->userData = (void*)data.userdata;
        shape->userData = (void*)data.userdata;
 
        return obj;
    }
 
    FSPhysXObject* FSPhysXWorld::createTreeObject(const IPhysXObjectData &data)
    {
        if (data.dynamic) return createDynamicTreeObject(data);
        else return createStaticTreeObject(data);
    }
 
    FSPhysXObject* FSPhysXWorld::createStaticTreeObject(const IPhysXObjectData &data)
    {
        FSPhysXObject_StaticTree* obj = new FSPhysXObject_StaticTree();
        obj->initialize();
        obj->create(this);
 
        if (data.mesh)
        {
            for (u32 x = 0; x < data.mesh->getMeshBufferCount(); x++)
                obj->addActor(createStaticTreeChunk(data, x));
        }
 
        obj->setRotation(data.rotation);
        return obj;
    }
 
    FSPhysXObject* FSPhysXWorld::createDynamicTreeObject(const IPhysXObjectData &data)
    {
        FSPhysXObject_DynamicTree* obj = new FSPhysXObject_DynamicTree();
        obj->initialize();
        obj->create(this);
 
        if (data.mesh)
        {
            for (u32 x = 0; x < data.mesh->getMeshBufferCount(); x++)
                obj->addActor(createDynamicTreeChunk(data, x));
        }
 
        obj->setRotation(data.rotation);
        return obj;
    }
 
    FSPhysXObject* FSPhysXWorld::createCharacterObject(const IPhysXObjectData &data)
    {
        FSPhysXObject_Character* obj = new FSPhysXObject_Character();
        obj->initialize();
        obj->create(this,data);
        return obj;
    }
 
    PxRigidStatic* FSPhysXWorld::createStaticTreeChunk(IPhysXObjectData data, int index)
    {
        PxTriangleMesh* triMesh = NULL;
        vector3df scale = data.scale;
 
        IMeshBuffer* meshBuffer = data.mesh->getMeshBuffer(index);
        PxVec3* verts = new PxVec3[meshBuffer->getVertexCount()];
        u32* indices = new u32[meshBuffer->getIndexCount()];
 
        switch (meshBuffer->getVertexType())
        {
        case video::EVT_STANDARD:
        {
            video::S3DVertex* vertices = (video::S3DVertex*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        case video::EVT_2TCOORDS:
        {
            video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        case video::EVT_TANGENTS:
        {
            video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        }
 
        for (u32 i = 0; i < meshBuffer->getIndexCount(); ++i)
            indices[i] = meshBuffer->getIndices()[i];
 
        //Cooking mesh
        PxTriangleMeshDesc meshDesc;
        meshDesc.points.count = meshBuffer->getVertexCount();
        meshDesc.triangles.count = meshBuffer->getIndexCount() / 3;
        meshDesc.points.stride = sizeof(PxVec3);
        meshDesc.triangles.stride = sizeof(PxU32) * 3;
        meshDesc.points.data = verts;
        meshDesc.triangles.data = indices;
        meshDesc.flags = PxMeshFlags(0);
 
        PxDefaultMemoryOutputStream stream;
        bool ok = getPhysXManager()->getCooking()->cookTriangleMesh(meshDesc, stream);
        PxDefaultMemoryInputData rb(stream.getData(), stream.getSize());
        PxTriangleMesh* triangleMesh = getPhysXManager()->getPhysXSDK()->createTriangleMesh(rb);
 
        if (!triangleMesh) { FS_LOG(FSL_WARNING, "WARNING traingle mesh is not valid"); return false; }
 
        PxRigidStatic* actor = getPhysXManager()->getPhysXSDK()->createRigidStatic(PxTransform(PxVec3(data.position.X, data.position.Y, data.position.Z)));
        if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addtreechunk() call"); return NULL; }
 
        PxShape* shape = actor->createShape(PxTriangleMeshGeometry(triangleMesh), *getPhysXManager()->m_DefaultMaterial);
        if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addtreechunk() call"); return NULL; }
 
        actor->userData = (void*)data.userdata;
        shape->userData = (void*)data.userdata;
 
        getScene()->addActor(*actor);
 
        return actor;
    }
 
    PxRigidDynamic* FSPhysXWorld::createDynamicTreeChunk(IPhysXObjectData data, int index)
    {
        vector3df scale = data.scale;
 
        IMeshBuffer* meshBuffer = data.mesh->getMeshBuffer(index);
        PxVec3* verts = new PxVec3[meshBuffer->getVertexCount()];
        u32* indices = new u32[meshBuffer->getIndexCount()];
 
        switch (meshBuffer->getVertexType())
        {
        case video::EVT_STANDARD:
        {
            video::S3DVertex* vertices = (video::S3DVertex*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        case video::EVT_2TCOORDS:
        {
            video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        case video::EVT_TANGENTS:
        {
            video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)meshBuffer->getVertices();
            for (u32 i = 0; i < meshBuffer->getVertexCount(); ++i)
                verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
            break;
        }
        }
 
        for (u32 i = 0; i < meshBuffer->getIndexCount(); ++i)
            indices[i] = meshBuffer->getIndices()[i];
 
        int indexcount = meshBuffer->getIndexCount() / 3;
        int vertexcount = meshBuffer->getVertexCount();
 
 
        //Cooking mesh
/*
        PxConvexMeshDesc meshDesc;
        meshDesc.points.count = vertexcount;
        meshDesc.triangles.count = indexcount;
        meshDesc.points.stride = sizeof(PxVec3);
        meshDesc.triangles.stride = sizeof(PxU32) * 3;
        meshDesc.points.data = verts;
        meshDesc.triangles.data = indices;
        meshDesc.flags = PxConvexFlags(0);
*/
 
        PxConvexMeshDesc convexDesc;
        convexDesc.points.count = vertexcount;
        convexDesc.points.stride = sizeof(PxVec3);
        convexDesc.points.data = verts;
        convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
        convexDesc.vertexLimit = 256;
 
//      PxDefaultMemoryOutputStream buf;
//      if (!cooking.cookConvexMesh(convexDesc, buf))return NULL;
 
        PxDefaultMemoryOutputStream stream;
        bool ok = getPhysXManager()->getCooking()->cookConvexMesh(convexDesc, stream);
        PxDefaultMemoryInputData rb(stream.getData(), stream.getSize());
        PxConvexMesh* convexMesh = getPhysXManager()->getPhysXSDK()->createConvexMesh(rb);
 
        if (!convexMesh) { FS_LOG(FSL_WARNING, "WARNING convex mesh is not valid"); return false; }
 
        PxRigidDynamic* actor = getPhysXManager()->getPhysXSDK()->createRigidDynamic(PxTransform(PxVec3(data.position.X, data.position.Y, data.position.Z)));
        if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in addtreechunk() call"); return NULL; }
 
        actor->setAngularDamping(1.0f);
        actor->setLinearDamping(1.0f);
        actor->setLinearVelocity(PxVec3(0, 0, 0));
        actor->setMass(data.mass);
 
        PxShape* shape = actor->createShape(PxConvexMeshGeometry(convexMesh), *getPhysXManager()->m_DefaultMaterial);
        if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in addtreechunk() call"); return NULL; }
 
        actor->userData = (void*)data.userdata;
        shape->userData = (void*)data.userdata;
 
        getScene()->addActor(*actor);
        return actor;
    }
 
 
    FSPhysXObject* FSPhysXWorld::createTerrainObject(const IPhysXObjectData &data)
    {
        // pointer to the terrain scenenode
        ITerrainSceneNode* terrain = dynamic_cast<ITerrainSceneNode*>(data.node);
 
        // make sure that we have a valid scenenode
        if (!terrain) { FS_LOG(FSL_WARNING, "WARNING PhysX createTerrainObject() terrain node is not valid"); return NULL; }
 
        // temporary variable
        CDynamicMeshBuffer buffer(EVT_2TCOORDS, EIT_16BIT);
 
        // get pointer to dynamic buffer for LOD 0
        terrain->getMeshBufferForLOD(buffer, 0);
 
        // remember the scale of the terrain
        vector3df scale = terrain->getScale();
 
        // allocate a temporary array of vertices
        PxVec3* verts = new PxVec3[buffer.getVertexCount()];
 
        // get a pointer to the vertices
        S3DVertex2TCoords* vertices = (S3DVertex2TCoords*)buffer.getVertices();
 
        // scale each vertex properly
        for (u32 i = 0; i < buffer.getVertexCount(); ++i)
            verts[i] = PxVec3(vertices[i].Pos.X * scale.X, vertices[i].Pos.Y * scale.Y, vertices[i].Pos.Z * scale.Z);
 
        // Cooking recipe
        PxTriangleMeshDesc meshDesc;
        meshDesc.points.count = buffer.getVertexCount();
        meshDesc.points.stride = sizeof(PxVec3);
        meshDesc.points.data = verts;
        meshDesc.triangles.count = buffer.getIndexCount() / 3;
        meshDesc.triangles.stride = sizeof(u16) * 3;
        meshDesc.triangles.data = buffer.getIndexBuffer().getData();
        meshDesc.flags = PxMeshFlag::e16_BIT_INDICES;
 
        // temproary variable
        PxDefaultMemoryOutputStream stream;
 
        // check the cooking result
        if (!getPhysXManager()->getCooking()->cookTriangleMesh(meshDesc, stream))
        {
            // log this event
            FS_LOG(FSL_WARNING, "WARNING PhysX createTerrainObject() cooktrianglemesh failed");
 
            // cleanup our memory mess
            delete[] verts;
 
            // bail......
            return NULL;
        }
 
        // create the triangle mesh
        PxDefaultMemoryInputData rb(stream.getData(), stream.getSize());
        PxTriangleMesh* triangleMesh = getPhysXManager()->getPhysXSDK()->createTriangleMesh(rb);
 
        // cleanup our memory mess
        delete[] verts;
 
        // check if the mesh is valid, return NULL if not
        if (!triangleMesh) { FS_LOG(FSL_WARNING, "WARNING traingle mesh is not valid"); return NULL; }
 
        // create the actor
        PxRigidStatic* actor = getPhysXManager()->getPhysXSDK()->createRigidStatic(PxTransform(PxVec3(data.position.X, data.position.Y, data.position.Z)));
        if (!actor) { FS_LOG(FSL_WARNING, "WARNING! actor is not valid in createTerrainObject() call"); return NULL; }
 
        // create the shape
        PxShape* shape = actor->createShape(PxTriangleMeshGeometry(triangleMesh), *getPhysXManager()->m_DefaultMaterial);
        if (!shape) { FS_LOG(FSL_WARNING, "WARNING! shape is not valid in createTerrainObject() call"); return NULL; }
 
        PxFilterData d = shape->getSimulationFilterData();
        d.word0 = FSOT_TERRAIN;
        d.word1 = 0xffffffff;
        shape->setQueryFilterData(d);
 
        // add the actor to the physx scene
        getScene()->addActor(*actor);
 
        actor->userData = (void*)data.userdata;
        shape->userData = (void*)data.userdata;
 
        // safely release the mesh
        if (triangleMesh) { triangleMesh->release(); triangleMesh = 0; }
 
        // create our physx object holder
        FSPhysXObject_RigidStatic* obj = new FSPhysXObject_RigidStatic();
            obj->initialize();      // initialize the object
            obj->create(this);      // create the object
            obj->setActor(actor);   // remember the actor
 
        obj->setRotation(data.rotation);
 
        // everything went fine, return our physx object
        return obj;
    }
 
} // end namespace
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

FSPhysXObject.cpp

Code: Select all

 
#include "FSUtils.h"
#include "FSPhysX.h"
#include "FSLogger.h"
 
namespace FS
{ 
    ///////////////////////////////////////////////////////////////////////////////
    // from irrlicht forums somewhere
    inline PxQuat EulerAngleToQuat(const PxVec3 &rot)
    {
        PxQuat qx(degToRad(rot.x), PxVec3(1.0f, 0.0f, 0.0f));
        PxQuat qy(degToRad(rot.y), PxVec3(0.0f, 1.0f, 0.0f));
        PxQuat qz(degToRad(rot.z), PxVec3(0.0f, 0.0f, 1.0f));
        return qz * qy * qx;
    }
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXObject_RigidDynamic::initialize()
    {
        // call the base class
        FSPhysXObject::initialize();
 
        // set to a known value
        m_Actor = 0;
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXObject_RigidDynamic::create(FSPhysXWorld* world)
    {
        // call the base class
        FSPhysXObject::create(world);
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXObject_RigidDynamic::cleanup()
    {
        // safely release the actor
        if (m_Actor) { m_Actor->release(); m_Actor = 0; }
 
        // call the base class
        return FSPhysXObject::cleanup();
    }
 
    vector3df FSPhysXObject_RigidDynamic::getPosition()
    {
        vector3df pos(0, 0, 0);
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            pos.set(tx.p.x, tx.p.y, tx.p.z);
        }
        return pos;
    }
 
    vector3df FSPhysXObject_RigidDynamic::getRotation()
    {
        vector3df rot(0, 0, 0);
        if (getActor())
        {
            PxMat33 mat = PxMat33::PxMat33(getActor()->getGlobalPose().q);
            irr::core::matrix4 irrM;
            irr::f32 fM[16];
            fM[0] = mat.column0.x;
            fM[1] = mat.column0.y;
            fM[2] = mat.column0.z;
            fM[4] = mat.column1.x;
            fM[5] = mat.column1.y;
            fM[6] = mat.column1.z;
            fM[8] = mat.column2.x;
            fM[9] = mat.column2.y;
            fM[10] = mat.column2.z;
            fM[15] = 1.0;
            irrM.setM(fM);
            rot = irrM.getRotationDegrees();
        }
        return rot;
    }
 
    void FSPhysXObject_RigidDynamic::setPosition(vector3df pos)
    {
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            tx.p.x = pos.X;
            tx.p.y = pos.Y;
            tx.p.z = pos.Z;
            getActor()->setGlobalPose(tx);
        }
    }
 
    void FSPhysXObject_RigidDynamic::setRotation(vector3df rot)
    {
        matrix4 irrM;
        irrM.setRotationDegrees(rot);
        PxTransform xform = getActor()->getGlobalPose();
        quaternion q(irrM);
        xform.q.w = q.W;
        xform.q.x = q.X;
        xform.q.y = q.Y;
        xform.q.z = q.Z;
        getActor()->setGlobalPose(xform);
    }
 
    void FSPhysXObject_RigidDynamic::getPositionAndRotation(vector3df &pos, vector3df &rot)
    {
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            pos.set(tx.p.x, tx.p.y, tx.p.z);
 
            PxMat33 mat = PxMat33::PxMat33(tx.q);
            irr::core::matrix4 irrM;
 
            irr::f32 fM[16];
            fM[0] = mat.column0.x;
            fM[1] = mat.column0.y;
            fM[2] = mat.column0.z;
            fM[4] = mat.column1.x;
            fM[5] = mat.column1.y;
            fM[6] = mat.column1.z;
            fM[8] = mat.column2.x;
            fM[9] = mat.column2.y;
            fM[10] = mat.column2.z;
 
            irrM.setM(fM);
            rot = irrM.getRotationDegrees();
        }
    }
 
    // add a force to the object
    void FSPhysXObject_RigidDynamic::addForce(vector3df dir, float magnitude)
    {
        if (getActor())
        {
            vector3df v = dir * magnitude;
            PxVec3 f(v.X, v.Y, v.Z);
            getActor()->setLinearVelocity(f);
        }
    }
 
    void FSPhysXObject_RigidDynamic::setFreeze(bool value)
    {
        if (getActor())
        {
            if (!value) getActor()->wakeUp();
            else getActor()->putToSleep();
        }
    }
    void FSPhysXObject_RigidDynamic::setMass(float value)
    {
        if (getActor()) getActor()->setMass(value);
    }
    float FSPhysXObject_RigidDynamic::getMass()
    {
        if (getActor()) return getActor()->getMass();
        return 0;
    }
    void FSPhysXObject_RigidDynamic::setLinearDamping(float value)
    {
        if (getActor()) getActor()->setLinearDamping(value);
    }
 
    void FSPhysXObject_RigidDynamic::setAngularDamping(float value)
    {
        if (getActor()) getActor()->setAngularDamping(value);
    }
 
    void FSPhysXObject_RigidDynamic::rotate(vector3df rotOffset)
    {
        if (getActor())
        {
            vector3df rot = getRotation();
            rot.X = 0;
            rot.Z = 0;
            rot.Y += rotOffset.Y;
            setRotation(rot);
        }
    }
 
    // attach this to an object
    void FSPhysXObject_RigidDynamic::setUserData(int id)
    {
        if (getActor())
        {
            getActor()->userData = (void*)id;
            PxShape* shapes[10];
            PxU32 nShapes = getActor()->getShapes(shapes, 10);
            while (nShapes--)
            {
                shapes[nShapes]->userData = (void*)id;
            }
        }
    }
 
    void FSPhysXObject_RigidDynamic::setObjectType(long t)
    {
        if (getActor())
        {
            PxShape* shapes[10];
            PxU32 nShapes = getActor()->getShapes(shapes, 10);
            while (nShapes--)
            {
                PxFilterData data = shapes[nShapes]->getSimulationFilterData();
                data.word0 = t;
 
                //shapes[nShapes]->setSimulationFilterData(PxFilterData(t, 0, 0, 0));
                shapes[nShapes]->setSimulationFilterData(data);
                shapes[nShapes]->setQueryFilterData(data);
                shapes[nShapes]->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
            }
        }
    }
 
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXObject_RigidStatic::initialize()
    {
        // call the base class
        FSPhysXObject::initialize();
 
        // set to a known value
        m_Actor = 0;
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXObject_RigidStatic::create(FSPhysXWorld* world)
    {
        // call the base class
        FSPhysXObject::create(world);
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXObject_RigidStatic::cleanup()
    {
        // safely release the actor
        if (m_Actor) { m_Actor->release(); m_Actor = 0; }
 
        // call the base class
        return FSPhysXObject::cleanup();
    }
 
    vector3df FSPhysXObject_RigidStatic::getPosition()
    {
        vector3df pos(0, 0, 0);
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            pos.set(tx.p.x, tx.p.y, tx.p.z);
        }
        return pos;
    }
 
    vector3df FSPhysXObject_RigidStatic::getRotation()
    {
        vector3df rot(0, 0, 0);
        if (getActor())
        {
            PxMat33 mat = PxMat33::PxMat33(getActor()->getGlobalPose().q);
            PxVec3 v = getActor()->getGlobalPose().p;
 
            irr::core::matrix4 irrM;
            irr::f32 fM[16];
            fM[0] = mat.column0.x;
            fM[1] = mat.column0.y;
            fM[2] = mat.column0.z;
            fM[4] = mat.column1.x;
            fM[5] = mat.column1.y;
            fM[6] = mat.column1.z;
            fM[8] = mat.column2.x;
            fM[9] = mat.column2.y;
            fM[10] = mat.column2.z;
            fM[15] = 0.0;
            irrM.setM(fM);
            irrM.setTranslation(vector3df(v.x, v.y, v.z));
            rot = irrM.getRotationDegrees();
        }
        return rot;
    }
 
    void FSPhysXObject_RigidStatic::setPosition(vector3df pos)
    {
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            tx.p.x = pos.X;
            tx.p.y = pos.Y;
            tx.p.z = pos.Z;
            getActor()->setGlobalPose(tx);
        }
    }
 
    void FSPhysXObject_RigidStatic::setRotation(vector3df rot)
    {
        matrix4 irrM;
        irrM.setRotationDegrees(rot);
        PxTransform xform = getActor()->getGlobalPose();
        quaternion q(irrM);
        xform.q.w = q.W;
        xform.q.x = q.X;
        xform.q.y = q.Y;
        xform.q.z = q.Z;
        getActor()->setGlobalPose(xform);
    }
 
    void FSPhysXObject_RigidStatic::getPositionAndRotation(vector3df &pos, vector3df &rot)
    {
        if (getActor())
        {
            PxTransform tx = getActor()->getGlobalPose();
            pos.set(tx.p.x, tx.p.y, tx.p.z);
 
            PxMat33 mat = PxMat33::PxMat33(tx.q);
            irr::core::matrix4 irrM;
 
            irr::f32 fM[16];
            fM[0] = mat.column0.x;
            fM[1] = mat.column0.y;
            fM[2] = mat.column0.z;
            fM[4] = mat.column1.x;
            fM[5] = mat.column1.y;
            fM[6] = mat.column1.z;
            fM[8] = mat.column2.x;
            fM[9] = mat.column2.y;
            fM[10] = mat.column2.z;
 
            irrM.setM(fM);
            rot = irrM.getRotationDegrees();
        }
    }
 
    void FSPhysXObject_RigidStatic::rotate(vector3df rotOffset)
    {
        if (getActor())
        {
            vector3df rot = getRotation();
            rot.X = 0;
            rot.Z = 0;
            rot.Y += rotOffset.Y;
            setRotation(rot);
        }
    }
 
    // attach this to an object
    void FSPhysXObject_RigidStatic::setUserData(int id)
    {
        if (getActor())
        {
            getActor()->userData = (void*)id;
            PxShape* shapes[10];
            PxU32 nShapes = getActor()->getShapes(shapes, 10);
            while (nShapes--)
            {
                shapes[nShapes]->userData = (void*)id;
            }
        }
    }
 
    void FSPhysXObject_RigidStatic::setObjectType(long t)
    {
        if (getActor())
        {
            PxShape* shapes[10];
            PxU32 nShapes = getActor()->getShapes(shapes, 10);
            while (nShapes--)
            {
                PxFilterData data = shapes[nShapes]->getSimulationFilterData();
                data.word0 = t;
                data.word1 = 0xffffffff;
                shapes[nShapes]->setSimulationFilterData(data);
                shapes[nShapes]->setQueryFilterData(data);
                shapes[nShapes]->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
            }
        }
    }
 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXObject_StaticTree::initialize()
    {
        // call the base class
        FSPhysXObject_RigidStatic::initialize();
 
        // set to a known value
        for (int x = 0; x<MAX_ACTORS; x++) m_Actors[x] = 0;
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXObject_StaticTree::create(FSPhysXWorld* world)
    {
        // call the base class
        FSPhysXObject_RigidStatic::create(world);
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXObject_StaticTree::cleanup()
    {
        // safely release the actors
        for (int x = 1; x < MAX_ACTORS; x++)
        {
            if (m_Actors[x]) { m_Actors[x]->release(); m_Actors[x] = 0; }
        }
 
        // call the base class
        return FSPhysXObject_RigidStatic::cleanup();
    }
 
    void FSPhysXObject_StaticTree::setPosition(vector3df pos)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                PxTransform tx = m_Actors[x]->getGlobalPose();
                tx.p.x = pos.X;
                tx.p.y = pos.Y;
                tx.p.z = pos.Z;
                m_Actors[x]->setGlobalPose(tx);
            }
        }
    }
 
    void FSPhysXObject_StaticTree::setRotation(vector3df rot)
    {
        for (int x = 0; x < MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                matrix4 irrM;
                irrM.setRotationDegrees(rot);
                PxTransform xform = m_Actors[x]->getGlobalPose();
                quaternion q(irrM);
                xform.q.w = q.W;
                xform.q.x = q.X;
                xform.q.y = q.Y;
                xform.q.z = q.Z;
                m_Actors[x]->setGlobalPose(xform);
            }
        }
    }
 
    void FSPhysXObject_StaticTree::addActor(PxRigidStatic* actor)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (!m_Actors[x])
            {
                m_Actors[x] = actor;
                if (x == 0)
                {
                    setActor(m_Actors[0]);
                }
                return;
            }
        }
    }
 
    // attach this to an object
    void FSPhysXObject_StaticTree::setUserData(int id)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                m_Actors[x]->userData = (void*)id;
                PxShape* shapes[10];
                PxU32 nShapes = m_Actors[x]->getShapes(shapes, 10);
                while (nShapes--)
                {
                    shapes[nShapes]->userData = (void*)id;
                }
            }
        }
    }
 
    void FSPhysXObject_StaticTree::setObjectType(long t)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                PxShape* shapes[10];
                PxU32 nShapes = m_Actors[x]->getShapes(shapes, 10);
                while (nShapes--)
                {
                    PxFilterData data = shapes[nShapes]->getSimulationFilterData();
                    data.word0 = t;
                    shapes[nShapes]->setSimulationFilterData(data);
                    shapes[nShapes]->setQueryFilterData(data);
                    shapes[nShapes]->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
                }
            }
        }
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
 
    // initialize the class. 
    // Set all variables to a known value
    void FSPhysXObject_DynamicTree::initialize()
    {
        // call the base class
        FSPhysXObject_RigidDynamic::initialize();
 
        // set to a known value
        for (int x = 0; x<MAX_ACTORS; x++) m_Actors[x] = 0;
    }
 
    // dual creation allows for better error handling. 
    // All class variables are valid after this call
    // return false on failure
    bool FSPhysXObject_DynamicTree::create(FSPhysXWorld* world)
    {
        // call the base class
        FSPhysXObject_RigidDynamic::create(world);
 
        // everything went fine
        return true;
    }
 
    // cleanup whatever memory mess we made.
    // all class variables are made invalid
    // always return false from a cleanup function
    bool FSPhysXObject_DynamicTree::cleanup()
    {
        // safely release the actors
        for (int x = 1; x < MAX_ACTORS; x++)
        {
            if (m_Actors[x]) { m_Actors[x]->release(); m_Actors[x] = 0; }
        }
 
        // call the base class
        return FSPhysXObject_RigidDynamic::cleanup();
    }
 
    void FSPhysXObject_DynamicTree::setPosition(vector3df pos)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                PxTransform tx = m_Actors[x]->getGlobalPose();
                tx.p.x = pos.X;
                tx.p.y = pos.Y;
                tx.p.z = pos.Z;
                m_Actors[x]->setGlobalPose(tx);
            }
        }
    }
 
    void FSPhysXObject_DynamicTree::setRotation(vector3df rot)
    {
        for (int x = 0; x < MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                matrix4 irrM;
                irrM.setRotationDegrees(rot);
                PxTransform xform = m_Actors[x]->getGlobalPose();
                quaternion q(irrM);
                xform.q.w = q.W;
                xform.q.x = q.X;
                xform.q.y = q.Y;
                xform.q.z = q.Z;
                m_Actors[x]->setGlobalPose(xform);
            }
        }
    }
 
    void FSPhysXObject_DynamicTree::addActor(PxRigidDynamic* actor)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (!m_Actors[x])
            {
                m_Actors[x] = actor;
                if (x == 0)
                {
                    setActor(m_Actors[0]);
                }
                return;
            }
        }
    }
 
    // attach this to an object
    void FSPhysXObject_DynamicTree::setUserData(int id)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                m_Actors[x]->userData = (void*)id;
                PxShape* shapes[10];
                PxU32 nShapes = m_Actors[x]->getShapes(shapes, 10);
                while (nShapes--)
                {
                    shapes[nShapes]->userData = (void*)id;
                }
            }
        }
    }
 
    void FSPhysXObject_DynamicTree::setObjectType(long t)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Actors[x])
            {
                PxShape* shapes[10];
                PxU32 nShapes = m_Actors[x]->getShapes(shapes, 10);
                while (nShapes--)
                {
                    PxFilterData data = shapes[nShapes]->getSimulationFilterData();
                    data.word0 = t;
                    shapes[nShapes]->setSimulationFilterData(data);
                    shapes[nShapes]->setQueryFilterData(data);
                    shapes[nShapes]->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
                }
            }
        }
    }
 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
 
    ControllerHitReport gControllerHitReport;
 
    void FSPhysXObject_Character::initialize()
    {
        FSPhysXObject::initialize();
        m_Controller = 0;
        m_Jumping = false;
        m_JumpTime = 0;
        m_Crouching = false;
        m_TotalForce.set(0, 0, 0);
        m_MaxJumpTime = 2;
        m_JumpFinished = false;
    }
 
    bool FSPhysXObject_Character::create(FSPhysXWorld* world, IPhysXObjectData data)
    {
        if (!FSPhysXObject::create(world)) return false;
 
        #define SKINWIDTH   0.0001f
        
        PxF32   gInitialRadius = data.scale.X;
        PxF32   gInitialHeight = data.scale.Y;
 
        if (data.node)
        {
            gInitialRadius = data.node->getBoundingBox().getExtent().X / 3 *data.scale.X;
            gInitialHeight = data.node->getBoundingBox().getExtent().Y / 2 *data.scale.Y;
        }
 
        PxCapsuleControllerDesc desc;
        desc.position.x         = data.position.X;
        desc.position.y         = data.position.Y;
        desc.position.z         = data.position.Z;
        desc.radius             = gInitialRadius;
        desc.height             = gInitialHeight;
        desc.upDirection        = PxVec3(0,1,0);
        desc.slopeLimit         = cosf(degToRad(45.0f));
        desc.stepOffset         = 0.02f;
//      desc..callback          = &gControllerHitReport;
        desc.userData           = (void*)data.userdata;
        desc.scaleCoeff         = 0.9f;
        desc.volumeGrowth       = 1.2f;
        desc.density            = 10;
        desc.material           = getWorld()->getPhysXManager()->m_DefaultMaterial;
//      m_Controller = world->getControllerManager()->createController(*getWorld()->getPhysXManager()->m_PhysXSDK, getWorld()->getScene(), desc);
        m_Controller = world->getControllerManager()->createController(desc);
        m_Controller->setUserData((void*)data.userdata);
        m_Controller->getActor()->userData = (void*)data.userdata;
        
        //m_Controller->setContactOffset(-1.0f);
 
        if (!m_Controller) { FS_LOG(FSL_WARNING, "FSPhysXObject_Character::create() Controller creaation failed"); return NULL; }
 
        // everything went fine
        return true;
    }
 
    bool FSPhysXObject_Character::cleanup()
    {
        // safely release the controller
        if (m_Controller) { m_Controller->release(); m_Controller = 0; }
 
        // always return false form a cleanup function
        return FSPhysXObject::cleanup();
    }
 
    vector3df FSPhysXObject_Character::getPosition()
    {
        vector3df pos(0, 0, 0);
        if (getController())
        {
            PxExtendedVec3 p = getController()->getPosition();
            pos.set((float)p.x, (float)p.y, (float)p.z);
        }
        return pos;
    }
 
    void FSPhysXObject_Character::setPosition(vector3df pos)
    {
        PxExtendedVec3 p(pos.X, pos.Y, pos.Z);
        if (getController()) getController()->setPosition(p);
    }
 
    void FSPhysXObject_Character::drawDebugInfo(SColor color)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
 
        // get a pointer to the device
        IrrlichtDevice* device = getWorld()->getPhysXManager()->getDevice();
        core::matrix4 mat;
        video::SMaterial material;
        material.TextureLayer->Texture = 0;
        material.Lighting = false;
        device->getVideoDriver()->setMaterial(material);
        device->getVideoDriver()->setTransform(video::ETS_WORLD, core::matrix4());
 
        {
            PxBounds3 dest = getController()->getActor()->getWorldBounds();
            const core::aabbox3d<f32> box(dest.minimum.x, dest.minimum.y, dest.minimum.z, dest.maximum.x, dest.maximum.y, dest.maximum.z);
            device->getVideoDriver()->draw3DBox(box, color);
        }
 
    }
 
    void FSPhysXObject_Character::setFreeze(bool value)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
        if (!value) m_Controller->getActor()->wakeUp();
        else m_Controller->getActor()->putToSleep();
    }
    void FSPhysXObject_Character::setMass(float value)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
        m_Controller->getActor()->setMass(value);
    }
    float FSPhysXObject_Character::getMass()
    {
        if (!m_Controller) return 1;
        if (!m_Controller->getActor()) return 1;
        return m_Controller->getActor()->getMass();
    }
    void FSPhysXObject_Character::setLinearDamping(float value)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
        m_Controller->getActor()->setLinearDamping(value);
    }
 
    void FSPhysXObject_Character::setAngularDamping(float value)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
        m_Controller->getActor()->setAngularDamping(value);
    }
 
    void FSPhysXObject_Character::addForce(vector3df dir, float force)
    {
        if (!m_Controller) return;
        if (!m_Controller->getActor()) return;
 
        dir.normalize();
        PxVec3 disp = PxVec3(dir.X, dir.Y, dir.Z) * force;
        m_TotalForce += vector3df(disp.x, disp.y, disp.z);
    }
 
 
    PxU32 FSPhysXObject_Character::moveCharacter(const PxVec3& dispVector, PxF32 elapsedTime, PxU32 collisionGroups)
    {
        if (!m_Controller) return 0;
        if (!m_Controller->getActor()) return 0;
 
        PxF32 sharpness = 1.0f;
        PxVec3 d = dispVector*elapsedTime;
 
        const PxU32 collisionFlags = m_Controller->move(d, -100, elapsedTime, NULL); // PxControllerFilters());
        return collisionFlags;
    }
 
    void FSPhysXObject_Character::frame(const float &elapsedtime)
    {
        float et = 1.0f / 60.0f; // elapsedtime;
        
        // add the gravity each frame
        PxVec3 disp(0, -132, 0);
 
        vector3df tf = getTotalForce();
        m_TotalForce = vector3df(0, 0, 0);
 
        disp += PxVec3(tf.X, tf.Y, tf.Z);
        disp.y += getHeight(et);
 
        PxU32 collisionFlags = moveCharacter(disp, et, 0);
        if (m_Jumping)  if (collisionFlags) stopJumping();
    }
 
    bool FSPhysXObject_Character::filter(const PxController& a, const PxController& b)
    {
        return true;
    }
 
 
    void FSPhysXObject_Character::jump()
    {
        if (m_Jumping) return;
        m_JumpTime = 0.0f;
        m_Jumping = true;
        m_JumpFinished = false;
    }
 
    void FSPhysXObject_Character::stopJumping()
    {
        m_Jumping = false;
        m_JumpTime = 0.0f;
        m_JumpFinished = true;
    }
 
    PxF32 FSPhysXObject_Character::getHeight(PxF32 elapsedTime)
    {
        m_MaxJumpTime = 2;
 
        //if (m_Crouching) return 0;
        if (!m_Jumping) return 0.0f;
 
        float G = 32.0f;
        float mV0 = 3.0f;
 
        m_JumpTime += elapsedTime;
        PxF32 h = G*m_JumpTime*m_JumpTime + mV0*m_JumpTime;
 
        if (m_JumpTime > m_MaxJumpTime) return 0;
    
//      return 65;
        return (32+h); //*elapsedTime;
    }
 
    void FSPhysXObject_Character::crouch(bool v)
    {
        if (m_Jumping) return;
        if (m_Crouching == v) return;
 
        if (m_Crouching)
        {
            // stand up
            getController()->resize(20);
        }
        else
        {
            // crouch down
            getController()->resize(40);
        }
        m_Crouching = v;
    }
 
    // attach this to an object
    void FSPhysXObject_Character::setUserData(int id)
    {
        for (int x = 0; x<MAX_ACTORS; x++)
        {
            if (m_Controller)
            {
                m_Controller->getActor()->userData = (void*)id;
                PxShape* shapes[10];
                PxU32 nShapes = m_Controller->getActor()->getShapes(shapes, 10);
                while (nShapes--)
                {
                    shapes[nShapes]->userData = (void*)id;
                }
            }
        }
    }
 
    void FSPhysXObject_Character::setObjectType(long t)
    {
        if (getActor())
        {
            PxShape* shapes[10];
            PxU32 nShapes = m_Controller->getActor()->getShapes(shapes, 10);
            while (nShapes--)
            {
                PxFilterData data = shapes[nShapes]->getSimulationFilterData();
                data.word0 = t;
                data.word1 = 0xffffffff;
                shapes[nShapes]->setSimulationFilterData(data);
                shapes[nShapes]->setQueryFilterData(data);
                shapes[nShapes]->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
 
            }
        }
    }
 
} // end namespace
 
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: IrrPhisx

Post by Seven »

ok, that's a lot of code for you to look through. it is integrated into my programming so a little hard to explain every aspect of it, but it should give you a good start for making your own. I am headed on vacation starting tomorrow for a week so I wont be checking here until I get back.

if there is enogh interest, maybe I will create a standalone like IrrPhysX was and make a little demo or two.
anyhow, enjoy and we can chat when I return.
Pinic
Posts: 21
Joined: Wed Mar 07, 2018 10:55 am

Re: IrrPhisx

Post by Pinic »

Seven wrote:ok, that's a lot of code for you to look through. it is integrated into my programming so a little hard to explain every aspect of it, but it should give you a good start for making your own. I am headed on vacation starting tomorrow for a week so I wont be checking here until I get back.

if there is enogh interest, maybe I will create a standalone like IrrPhysX was and make a little demo or two.
anyhow, enjoy and we can chat when I return.
Thank you! Soon I will try to use your code)
Post Reply