Linker error's wis PhysX

Started by
7 comments, last by ankhd 9 years ago

Hi all.

I'm just starting out with the physX api with a consol app that displays
the position of a ball droped from 100 units in the Y+ that falls this all worked
file.

The problem is I had all the code for the sample in the main cpp file
but when I went to create a class in its own header and source file and include these 2 file
in the same app as above I get this lot of errors.
.


1>libcmtd.lib(typinfo.obj) : error LNK2005: "public: void __thiscall type_info::_type_info_dtor_internal_method(void)" (?_type_info_dtor_internal_method@type_info@@QAEXXZ) already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(typinfo.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in MSVCRTD.lib(ti_inst.obj)
1>libcmtd.lib(typinfo.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in MSVCRTD.lib(ti_inst.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: __CrtSetDbgFlag already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: __aligned_malloc already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: __aligned_free already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(mlock.obj) : error LNK2005: __lock already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(mlock.obj) : error LNK2005: __unlock already defined in MSVCRTD.lib(MSVCR100D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR100D.dll)

.

After some time I found a solution by placing the.

.


#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib, "PhysX3DEBUG_x86.lib")
#pragma comment(lib, "PhysXProfileSDKDEBUG.lib")
#pragma comment(lib, "PhysX3ExtensionsDEBUG.lib")
#pragma comment(lib, "PhysX3CommonDEBUG_x86.lib")

#else
#pragma comment(lib, "PhysX3_x86.lib")
#pragma comment(lib, "PhysXProfileSDK.lib")
#pragma comment(lib, "PhysX3Extensions.lib")
#pragma comment(lib, "PhysX3Common_x86.lib")
#endif

.

with in the new .h file I created(It was in the main.cpp file where all the libs go). I've never had to do any thing like that before.
Have I done some thing wrog or is that normal.

Advertisement

Hey ankhd,

So the reason you were initially seeing these linking errors is probably because you are mixing code that was compiled with /MD (multi-threaded DLL) with code that was compiled with /MT (multi-threaded).

At a guess, your project's runtime library settings (Configuration Properties->C/C++->Code Generation->Runtime Library, assuming you're using Visual Studio) doesn't match that of the PhysX binaries you were linking to.

So the reason you were initially seeing these linking errors is probably because you are mixing code that was compiled with /MD (multi-threaded DLL) with code that was compiled with /MT (multi-threaded).


That does not look to me like that at all. This seems to be the classical debug/non-debug runtime dilemma. Note that he fixed it by linking (or not linking) the debug PhysX libraries instead of the release libraries, so the problem should be /MD versus /MDd (or perhaps less likely /MT versus /MTd).

Anyway, that is something you need to deal with when using MSVC. The runtime libraries for debug and non-debug builds cannot be mixed inside the same target. I also strongly recommend you learn to deal with the issue, not avoid it. For anything non-trivial you will need a working debug and release build.

Note that using a build system like for example CMake can often handle the problem for you. Assuming there is a decent find-script for PhysX (possible but never tried by me) CMake can automatically link the correct libraries to the respective builds without your intervention.


That does not look to me like that at all. This seems to be the classical debug/non-debug runtime dilemma. Note that he fixed it by linking (or not linking) the debug PhysX libraries instead of the release libraries, so the problem should be /MD versus /MDd (or perhaps less likely /MT versus /MTd).

Hah hah, yeah definitely :)

Hi.

I think the physx lib is MT, But on a lot of other forums, there all saying that the physx is MD, how come now its MT.

I can't find any vc solution to compile the libs to MD The only files in the SDK PhysX is PhysXExtensions.sln(I built this one), PhysXVehicle.sln, but the Physx PhysX3_x86.lib build solution is nowhere to be seen.

Does this statement hold true MT will pack the lib within the exe. if thats true the physx doc says we need to ship there dll with the app ???.

I can't use MT its fine for my test app but the rest of the apps I would like to add physx to use MD, boost, google protocol buffers.

A dumb Question??? if I compile the project with MT when the app closes the memory leak pops up.

I am using this here to detect memory leaks.

.


   // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

Does the above not work with MT(I think MT holds its own copy of the lib).

heres the app in its current form using MD setup.

But Im doing the class wrong because I need to #progma in the . Hpp file I think its tricking the compiler to work.???

.


#ifndef PHYSX_H
#define PHYSX_H        

#include <iostream>
#include <pxphysicsapi.h>
#include <extensions//pxdefaulterrorcallback.h>
#include <extensions//pxdefaultallocator.h>


//#include <string>


//to use this class you will need to include the following libs
//and also copy to the apps root folder
//nvToolsExt32_1.dll
//PhysX3_x86.dll
//PhysX3Common_x86.dll
//PhysX3CommonDEBUG_x86.dll
//PhysX3DEBUG_x86.dll
//don't include the debug dll's in release 

//THIS BIT HERE IS BAD ???????????????????
//also you need to link the following libs in vc
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib, "PhysX3DEBUG_x86.lib")
#pragma comment(lib, "PhysXProfileSDKDEBUG.lib")
#pragma comment(lib, "PhysX3ExtensionsDEBUG.lib")
#pragma comment(lib, "PhysX3CommonDEBUG_x86.lib")

#else
#pragma comment(lib, "PhysX3_x86.lib")
#pragma comment(lib, "PhysXProfileSDK.lib")
#pragma comment(lib, "PhysX3Extensions.lib")
#pragma comment(lib, "PhysX3Common_x86.lib")
#endif



//------------------------------------------------------------------------------
//this class will initialize the physX objects and scene and 
//you will need to call releasePhysX
//------------------------------------------------------------------------------
class cPhysX
{
public:

	cPhysX();
	~cPhysX();


	void ShutdownPhysX();


	//----------------------------------------------------------------------
	//if the debug flag is true we create the profilemanager
	//----------------------------------------------------------------------
	bool InitializePhysX(bool ddg);



	//public members

	physx::PxFoundation *gFoundation;
	physx::PxPhysics *gPhysicsSDK;

	physx::PxDefaultCpuDispatcher*	gDispatcher;
	physx::PxScene *gScene;

	physx::PxDefaultErrorCallback gDefaultErrorCallback;
	physx::PxDefaultAllocator gDefaultAllocatorCallback;
	physx::PxProfileZoneManager* gProfileZoneManager;


	//error message
	std::string ErrorMsg;

};//end class cPhysX
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////







#endif



Cpp file

.


cPhysX::cPhysX()
{

	gFoundation			= NULL;
	gPhysicsSDK			= NULL;
	gDispatcher			= NULL;
	gScene				= NULL;
	gProfileZoneManager = NULL;


}//end con
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////






cPhysX::~cPhysX()
{
	

}//end destructor
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////






void cPhysX::ShutdownPhysX() 
{ 
	if(gScene)
		gScene->release();

	if(gDispatcher)
		gDispatcher->release();
	
	if(gPhysicsSDK)
		gPhysicsSDK->release();

	if(gProfileZoneManager)
		gProfileZoneManager->release();

	if(gFoundation)
		gFoundation->release();

	gFoundation			= NULL;
	gPhysicsSDK			= NULL;
	gDispatcher			= NULL;
	gScene				= NULL;
	gProfileZoneManager = NULL;

}//end ShutdownPhysX
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////








//----------------------------------------------------------------------
//if the debug flag is true we create the profilemanager
//----------------------------------------------------------------------
bool cPhysX::InitializePhysX(bool ddg) 
{   
	if(gFoundation)
		return true;

	ErrorMsg = "No Errors";

	gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);	
	if(gFoundation == NULL)
	{ 
		ErrorMsg = "Error creating gFoundation."; 
		return false;
	}


	if(ddg)
	{
		gProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(gFoundation);
		if(gProfileZoneManager == NULL)
		{ 
			ErrorMsg = "Error creating gProfileZoneManager."; 
			return false;
		}
	}


	bool recordMemoryAllocations = ddg;

	gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, physx::PxTolerancesScale(), recordMemoryAllocations, gProfileZoneManager);
	if(gPhysicsSDK == NULL) 
	{ 
		ErrorMsg = "Error creating PhysX device."; 
	
		return false;   
	}


	return true;//all ok

}//end InitializePhysX
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Main.Cpp

.



#include <iostream>
#include <vector>
#include<physx.h>


/*
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib, "PhysX3DEBUG_x86.lib")
#pragma comment(lib, "PhysXProfileSDKDEBUG.lib")
#pragma comment(lib, "PhysX3ExtensionsDEBUG.lib")
#pragma comment(lib, "PhysX3CommonDEBUG_x86.lib")

#else
#pragma comment(lib, "PhysX3_x86.lib")
#pragma comment(lib, "PhysXProfileSDK.lib")
#pragma comment(lib, "PhysX3Extensions.lib")
#pragma comment(lib, "PhysX3Common_x86.lib")
#endif
*/
//#include <pxphysicsapi.h>
//#include <extensions//pxdefaulterrorcallback.h>
//#include <extensions//pxdefaultallocator.h>



//The PhysX header is now PxPhysicsAPI.h. This header is needed for PhysX. The rest are for c++ output/input stuff and 
//freeglut API stuff. I like to programmatically add the linker libraries. 
//For this basic startup demo, we need PhysX3_x86.lib/dll, Foundation.lib/dll, PhysX3Extensions.lib/dll so we link to them.

//const int WINDOW_WIDTH=1024, WINDOW_HEIGHT=768;
//physx::PxFoundation *gFoundation = nullptr;
//physx::PxPhysics *gPhysicsSDK = nullptr;

//physx::PxDefaultCpuDispatcher*	gDispatcher = NULL;
//physx::PxScene *gScene = nullptr;

//physx::PxDefaultErrorCallback gDefaultErrorCallback;
//physx::PxDefaultAllocator gDefaultAllocatorCallback;
//physx::PxProfileZoneManager* gProfileZoneManager = nullptr;

//IN the above lines, we setup the window dimensions. Then we store the PhysX object pointer. In the previous sdk, 
//only first parameter was needed now all of the parameters are needed. These include the allocator and error callback handlers. 
//The sdk provides default handlers so we use them.

//Thats it. The code should not give u any errors. To make sure everything is fine and there are no problems, 
//copy PhysX3_x86.dll to the current solution directory. Hope you will enjoy the rest of the tutorials.




/*
void InitializePhysX() 
{   
	gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);	
	if(gFoundation == nullptr)
	{ 
		std::cerr<<"Error creating gFoundation."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}


	gProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(gFoundation);
	if(gProfileZoneManager == nullptr)
	{ 
		std::cerr<<"Error creating gProfileZoneManager."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}

	bool recordMemoryAllocations = true;

	gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, physx::PxTolerancesScale(), recordMemoryAllocations, gProfileZoneManager);
	if(gPhysicsSDK == nullptr) 
	{ 
		std::cerr<<"Error creating PhysX device."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}
}

void ShutdownPhysX() 
{ 
	gScene->release();
	gDispatcher->release();

	gPhysicsSDK->release();


	gProfileZoneManager->release();
	gFoundation->release();

}
*/



//How do I convert a quaternion to a rotation axis and angle?
//----------------------------------------------------------------
// A quaternion can be converted back to a rotation axis and angle
//using the following algorithm:
//---------------------------------------------------
void QuaternionToAxisAngle(physx::PxVec3 &axis, physx::PxQuat &qr1)
{
	physx::PxQuat qr = qr1;
	qr.normalize();

	double PI = 3.14159265;
	double RADIANS =  (180 / PI); //

    double cos_angle  = qr.w;
    double angle      = acos( cos_angle ) * 2 * RADIANS;
    double sin_angle  = sqrt( 1.0 - cos_angle * cos_angle );

	double sa = sin_angle;
    if ( fabs( sin_angle ) < 0.0005 )
      sa = 1;

    axis.x = qr.x / sa;
    axis.y = qr.y / sa;
    axis.z = qr.z / sa;

}



physx::PxFilterFlags contactReportFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, 
										physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1,
										physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
{
	PX_UNUSED(attributes0);
	PX_UNUSED(attributes1);
	PX_UNUSED(filterData0);
	PX_UNUSED(filterData1);
	PX_UNUSED(constantBlockSize);
	PX_UNUSED(constantBlock);

	// all initial and persisting reports for everything, with per-point data
	pairFlags = physx::PxPairFlag::eRESOLVE_CONTACTS
			  |	physx::PxPairFlag::eNOTIFY_TOUCH_FOUND 
			  | physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS
			  | physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
	return physx::PxFilterFlag::eDEFAULT;
}


class ContactReportCallback: public physx::PxSimulationEventCallback
{
	void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count)	{ PX_UNUSED(constraints); PX_UNUSED(count); }
	void onWake(physx::PxActor** actors, physx::PxU32 count)							{ PX_UNUSED(actors); PX_UNUSED(count); }
	void onSleep(physx::PxActor** actors, physx::PxU32 count)							{ PX_UNUSED(actors); PX_UNUSED(count); }
	void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count)					{ PX_UNUSED(pairs); PX_UNUSED(count); }
	void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) 
	{
		PX_UNUSED((pairHeader));
		std::vector<physx::PxContactPairPoint> contactPoints;
		
		for(physx::PxU32 i=0;i<nbPairs;i++)
		{
			physx::PxU32 contactCount = pairs[i].contactCount;
			if(contactCount)
			{
				contactPoints.resize(contactCount);
				pairs[i].extractContacts(&contactPoints[0], contactCount);

				for(physx::PxU32 j=0;j<contactCount;j++)
				{
					//lost shapes we dont want
					if( pairs[i].events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND)
					{
						if(pairs[i].shapes[0]->getActor()->userData)
						{
							int *ballid = reinterpret_cast<int*>(pairs[i].shapes[0]->getActor()->userData);
							std::cout << "**********************OnCollision Ball ID = " << *ballid << " Shape Number = 0" <<std::endl;
							std::getchar();
						}
						if(pairs[i].shapes[1]->getActor()->userData)
						{
							int *ballid = reinterpret_cast<int*>(pairs[i].shapes[1]->getActor()->userData);

							std::cout << "**********************OnCollision Ball ID = " << *ballid << " Shape Number = 1" <<std::endl;
							std::getchar();
						}
					}

					//gContactPositions.push_back(contactPoints[j].position);
					//gContactImpulses.push_back(contactPoints[j].impulse);
				}
			}
		}
	}
};

ContactReportCallback gContactReportCallback;

int main(int argc, char* argv[])
{															
       // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif



	//InitializePhysX();
	
	cPhysX PhysX;

	int BallID = 3;
	
	//we want to check memorey true debug only
	if(PhysX.InitializePhysX(true) == false)
	{
		std::cout << "Error creating PhysX device." << PhysX.ErrorMsg.c_str() << std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1); 
	}


	//we create the scene out side
	physx::PxSceneDesc sceneDesc(PhysX.gPhysicsSDK->getTolerancesScale());
	sceneDesc.gravity = physx::PxVec3(0.0f, -9.81f, 0.0f);

	PhysX.gDispatcher = physx::PxDefaultCpuDispatcherCreate(1);
	sceneDesc.cpuDispatcher	=PhysX.gDispatcher;
	sceneDesc.filterShader	= contactReportFilterShader;//physx::PxDefaultSimulationFilterShader;
	sceneDesc.simulationEventCallback = &gContactReportCallback;
	PhysX.gScene = PhysX.gPhysicsSDK->createScene(sceneDesc);


	//we want a ball we will drop it down
	physx::PxSphereGeometry gSphereGeometry(20);
	physx::PxTransform t(physx::PxVec3(0,100,0));

	physx::PxMaterial *gMaterialSphere	= NULL;

	physx::PxMaterial *gMaterialPlane = NULL;

	gMaterialSphere = PhysX.gPhysicsSDK->createMaterial(0.01f, 0.01f, 1.0f);

	gMaterialPlane = PhysX.gPhysicsSDK->createMaterial(0.5f, 0.5f, 0.0f);

	physx::PxVec3 velocity = physx::PxVec3(0,-60,0);

	physx::PxRigidDynamic* dynamic = physx::PxCreateDynamic(*PhysX.gPhysicsSDK, t, gSphereGeometry, *gMaterialSphere, 1000.0f);
	dynamic->setAngularDamping(0.0f);
	dynamic->setLinearVelocity(velocity);

	dynamic->userData = (void*)&BallID;

	PhysX.gScene->addActor(*dynamic);



	//ground plane
	physx::PxRigidStatic* groundPlane = physx::PxCreatePlane(*PhysX.gPhysicsSDK, physx::PxPlane(0,1,0,0), *gMaterialPlane);
	PhysX.gScene->addActor(*groundPlane);

physx::PxShape* shapes[10];
std::vector<physx::PxRigidActor*> actors;
	//test update
	for(int ctr = 0; ctr < 600; ++ctr)
	{
		PhysX.gScene->simulate(0.01666);//1.0f/60.0f);
		PhysX.gScene->fetchResults(true);

		//print the balls position | physx::PxActorTypeSelectionFlag::eRIGID_STATIC
		physx::PxU32 nbActors = PhysX.gScene->getNbActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC );
		if(nbActors)
		{
			actors.resize(nbActors);// | physx::PxActorTypeSelectionFlag::eRIGID_STATIC
			PhysX.gScene->getActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC, (physx::PxActor**)&actors[0], nbActors);
			
			
			for(physx::PxU32 i=0;i<actors.size();i++)
			{
				const physx::PxU32 nbShapes = actors[i]->getNbShapes();
		
				actors[i]->getShapes(shapes, nbShapes);
				bool sleeping = actors[i]->isRigidDynamic() ? actors[i]->isRigidDynamic()->isSleeping() : false; 

				for(physx::PxU32 j=0;j<nbShapes;j++)
				{
					const physx::PxMat44 shapePose(physx::PxShapeExt::getGlobalPose(*shapes[j], *actors[i]));
					//PxGeometryHolder h = shapes[j]->getGeometry();

					
					//if (shapes[j]->getFlags() & physx::PxShapeFlag::eTRIGGER_SHAPE)
					physx::PxVec3 pos = shapePose.getPosition();
					std::cout << "sphere height: " << pos.y << " X = " << pos.x << " Z = " << pos.z << std::endl;	
					
					//physx::PxTransform Pose = actors[i]->getGlobalPose();
					//pos = Pose.p;
					//QuaternionToAxisAngle(pos, Pose.q);
					//std::cout << "Angle Axis sphere X: " << pos.x << " Y = " << pos.y << " Z = " << pos.z << std::endl;	
						

				}//end all shapes

			}//end all actors

		}//end nbactor

	}

	std::getchar();
	
	
	PhysX.ShutdownPhysX();
	
	

	return 0;
}

Notice if the code is in the main.cpp it compiles fine and runs.

I'm lost.

Oh I just found this.


Note:
 
The static libraries we provide with the Windows binary distribution are linked against the Multi-Threaded static C Run-Time (CRT) libraries. This means that your application must also use the same CRT flavor. If you need to use a different CRT version, you must upgrade to our source license. The source distribution can simply be recompiled using different CRT settings.
 

So the reason you were initially seeing these linking errors is probably because you are mixing code that was compiled with /MD (multi-threaded DLL) with code that was compiled with /MT (multi-threaded).


That does not look to me like that at all. This seems to be the classical debug/non-debug runtime dilemma. Note that he fixed it by linking (or not linking) the debug PhysX libraries instead of the release libraries, so the problem should be /MD versus /MDd (or perhaps less likely /MT versus /MTd).

That's exactly what it looks like to me. The error messages are pretty clear - it's finding definitions in both libcmtd.lib (static MT debug) and MSVCRTD.lib (dynamic MT debug).

Hello.

Can anyone see any problems in the .h and .ccp files I posted up there.

Because as soon as I include them in any app I get them compile errors. But if I copy and paste the members from my cPhysx class to within main its all fine.

Some of the physX tutorials use static in front of there physx variables

Is there away to tell if the libs are MT or MD MD is fine when there in the main.cpp

I'm all most ready to dump physx sdk because of this. bullet worked first up. Kudos to Bullet.

There is some thing wrong some where. The same build settings MD with the class cPhysX removed, compiles and runs with just this

.

LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library

just testing the release and debug build settings and the above warning is release build with MD the debug build with MD does not generate this warning. Why???????

release build MT no warnning, debug build with MT warning. what thay release there sdk with release build MT and debug build MD wtf.....?????????

here is the code with the cPhysX class removed it should not build but it does.??????

.




#include <iostream>
#include <vector>

#include <pxphysicsapi.h>
#include <extensions//pxdefaulterrorcallback.h>
#include <extensions//pxdefaultallocator.h>


//#include<physx.h>
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment(lib, "PhysX3DEBUG_x86.lib")
#pragma comment(lib, "PhysXProfileSDKDEBUG.lib")
#pragma comment(lib, "PhysX3ExtensionsDEBUG.lib")
#pragma comment(lib, "PhysX3CommonDEBUG_x86.lib")

#else
#pragma comment(lib, "PhysX3_x86.lib")
#pragma comment(lib, "PhysXProfileSDK.lib")
#pragma comment(lib, "PhysX3Extensions.lib")
#pragma comment(lib, "PhysX3Common_x86.lib")
#endif





//The PhysX header is now PxPhysicsAPI.h. This header is needed for PhysX. The rest are for c++ output/input stuff and 
//freeglut API stuff. I like to programmatically add the linker libraries. 
//For this basic startup demo, we need PhysX3_x86.lib/dll, Foundation.lib/dll, PhysX3Extensions.lib/dll so we link to them.

//const int WINDOW_WIDTH=1024, WINDOW_HEIGHT=768;
physx::PxFoundation *gFoundation = nullptr;
physx::PxPhysics *gPhysicsSDK = nullptr;
physx::PxDefaultCpuDispatcher*	gDispatcher = NULL;
physx::PxScene *gScene = nullptr;

physx::PxDefaultErrorCallback gDefaultErrorCallback;
physx::PxDefaultAllocator gDefaultAllocatorCallback;
physx::PxProfileZoneManager* gProfileZoneManager = nullptr;

//IN the above lines, we setup the window dimensions. Then we store the PhysX object pointer. In the previous sdk, 
//only first parameter was needed now all of the parameters are needed. These include the allocator and error callback handlers. 
//The sdk provides default handlers so we use them.

//Thats it. The code should not give u any errors. To make sure everything is fine and there are no problems, 
//copy PhysX3_x86.dll to the current solution directory. Hope you will enjoy the rest of the tutorials.





void InitializePhysX() 
{   
	gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);	
	if(gFoundation == nullptr)
	{ 
		std::cerr<<"Error creating gFoundation."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}


	gProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(gFoundation);
	if(gProfileZoneManager == nullptr)
	{ 
		std::cerr<<"Error creating gProfileZoneManager."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}

	bool recordMemoryAllocations = true;

	gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, physx::PxTolerancesScale(), recordMemoryAllocations, gProfileZoneManager);
	if(gPhysicsSDK == nullptr) 
	{ 
		std::cerr<<"Error creating PhysX device."<<std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1);   
	}
}

void ShutdownPhysX() 
{ 
	gScene->release();
	gDispatcher->release();

	gPhysicsSDK->release();


	gProfileZoneManager->release();
	gFoundation->release();

}




//How do I convert a quaternion to a rotation axis and angle?
//----------------------------------------------------------------
// A quaternion can be converted back to a rotation axis and angle
//using the following algorithm:
//---------------------------------------------------
void QuaternionToAxisAngle(physx::PxVec3 &axis, physx::PxQuat &qr1)
{
	physx::PxQuat qr = qr1;
	qr.normalize();

	double PI = 3.14159265;
	double RADIANS =  (180 / PI); //

    double cos_angle  = qr.w;
    double angle      = acos( cos_angle ) * 2 * RADIANS;
    double sin_angle  = sqrt( 1.0 - cos_angle * cos_angle );

	double sa = sin_angle;
    if ( fabs( sin_angle ) < 0.0005 )
      sa = 1;

    axis.x = qr.x / sa;
    axis.y = qr.y / sa;
    axis.z = qr.z / sa;

}



physx::PxFilterFlags contactReportFilterShader(physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0, 
										physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1,
										physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
{
	PX_UNUSED(attributes0);
	PX_UNUSED(attributes1);
	PX_UNUSED(filterData0);
	PX_UNUSED(filterData1);
	PX_UNUSED(constantBlockSize);
	PX_UNUSED(constantBlock);

	// all initial and persisting reports for everything, with per-point data
	pairFlags = physx::PxPairFlag::eRESOLVE_CONTACTS
			  |	physx::PxPairFlag::eNOTIFY_TOUCH_FOUND 
			  | physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS
			  | physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
	return physx::PxFilterFlag::eDEFAULT;
}


class ContactReportCallback: public physx::PxSimulationEventCallback
{
	void onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count)	{ PX_UNUSED(constraints); PX_UNUSED(count); }
	void onWake(physx::PxActor** actors, physx::PxU32 count)							{ PX_UNUSED(actors); PX_UNUSED(count); }
	void onSleep(physx::PxActor** actors, physx::PxU32 count)							{ PX_UNUSED(actors); PX_UNUSED(count); }
	void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count)					{ PX_UNUSED(pairs); PX_UNUSED(count); }
	void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs) 
	{
		PX_UNUSED((pairHeader));
		std::vector<physx::PxContactPairPoint> contactPoints;
		
		for(physx::PxU32 i=0;i<nbPairs;i++)
		{
			physx::PxU32 contactCount = pairs[i].contactCount;
			if(contactCount)
			{
				contactPoints.resize(contactCount);
				pairs[i].extractContacts(&contactPoints[0], contactCount);

				for(physx::PxU32 j=0;j<contactCount;j++)
				{
					//lost shapes we dont want
					if( pairs[i].events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND)
					{
						if(pairs[i].shapes[0]->getActor()->userData)
						{
							int *ballid = reinterpret_cast<int*>(pairs[i].shapes[0]->getActor()->userData);
							std::cout << "**********************OnCollision Ball ID = " << *ballid << " Shape Number = 0" <<std::endl;
							std::getchar();
						}
						if(pairs[i].shapes[1]->getActor()->userData)
						{
							int *ballid = reinterpret_cast<int*>(pairs[i].shapes[1]->getActor()->userData);

							std::cout << "**********************OnCollision Ball ID = " << *ballid << " Shape Number = 1" <<std::endl;
							std::getchar();
						}
					}

					//gContactPositions.push_back(contactPoints[j].position);
					//gContactImpulses.push_back(contactPoints[j].impulse);
				}
			}
		}
	}
};

ContactReportCallback gContactReportCallback;

int main(int argc, char* argv[])
{															
       // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif



	//InitializePhysX();
	
	//cPhysX PhysX;

	int BallID = 3;
	
	//we want to check memorey true debug only
	/*if(PhysX.InitializePhysX(true) == false)
	{
		std::cout << "Error creating PhysX device." << PhysX.ErrorMsg.c_str() << std::endl; 
	
		std::getchar();
		std::cerr<<"Exiting..."<<std::endl; exit(1); 
	}
	*/
	InitializePhysX();


	//we create the scene out side
	physx::PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale());
	sceneDesc.gravity = physx::PxVec3(0.0f, -9.81f, 0.0f);

	gDispatcher = physx::PxDefaultCpuDispatcherCreate(1);
	sceneDesc.cpuDispatcher	= gDispatcher;
	sceneDesc.filterShader	= contactReportFilterShader;//physx::PxDefaultSimulationFilterShader;
	sceneDesc.simulationEventCallback = &gContactReportCallback;
	gScene = gPhysicsSDK->createScene(sceneDesc);


	//we want a ball we will drop it down
	physx::PxSphereGeometry gSphereGeometry(20);
	physx::PxTransform t(physx::PxVec3(0,100,0));

	physx::PxMaterial *gMaterialSphere	= NULL;

	physx::PxMaterial *gMaterialPlane = NULL;

	gMaterialSphere = gPhysicsSDK->createMaterial(0.01f, 0.01f, 1.0f);

	gMaterialPlane = gPhysicsSDK->createMaterial(0.5f, 0.5f, 0.0f);

	physx::PxVec3 velocity = physx::PxVec3(0,-60,0);

	physx::PxRigidDynamic* dynamic = physx::PxCreateDynamic(*gPhysicsSDK, t, gSphereGeometry, *gMaterialSphere, 1000.0f);
	dynamic->setAngularDamping(0.0f);
	dynamic->setLinearVelocity(velocity);

	dynamic->userData = (void*)&BallID;

	gScene->addActor(*dynamic);



	//ground plane
	physx::PxRigidStatic* groundPlane = physx::PxCreatePlane(*gPhysicsSDK, physx::PxPlane(0,1,0,0), *gMaterialPlane);
	gScene->addActor(*groundPlane);



physx::PxShape* shapes[10];
std::vector<physx::PxRigidActor*> actors;
	//test update
	for(int ctr = 0; ctr < 600; ++ctr)
	{
		gScene->simulate(0.01666);//1.0f/60.0f);
		gScene->fetchResults(true);

		//print the balls position | physx::PxActorTypeSelectionFlag::eRIGID_STATIC
		physx::PxU32 nbActors = gScene->getNbActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC );
		if(nbActors)
		{
			actors.resize(nbActors);// | physx::PxActorTypeSelectionFlag::eRIGID_STATIC
			gScene->getActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC, (physx::PxActor**)&actors[0], nbActors);
			
			
			for(physx::PxU32 i=0;i<actors.size();i++)
			{
				const physx::PxU32 nbShapes = actors[i]->getNbShapes();
		
				actors[i]->getShapes(shapes, nbShapes);
				bool sleeping = actors[i]->isRigidDynamic() ? actors[i]->isRigidDynamic()->isSleeping() : false; 

				for(physx::PxU32 j=0;j<nbShapes;j++)
				{
					const physx::PxMat44 shapePose(physx::PxShapeExt::getGlobalPose(*shapes[j], *actors[i]));
					//PxGeometryHolder h = shapes[j]->getGeometry();

					
					//if (shapes[j]->getFlags() & physx::PxShapeFlag::eTRIGGER_SHAPE)
					physx::PxVec3 pos = shapePose.getPosition();
					std::cout << "sphere height: " << pos.y << " X = " << pos.x << " Z = " << pos.z << std::endl;	
					
					//physx::PxTransform Pose = actors[i]->getGlobalPose();
					//pos = Pose.p;
					//QuaternionToAxisAngle(pos, Pose.q);
					//std::cout << "Angle Axis sphere X: " << pos.x << " Y = " << pos.y << " Z = " << pos.z << std::endl;	
						

				}//end all shapes

			}//end all actors

		}//end nbactor

	}

	std::getchar();
	
	ShutdownPhysX();
	

	
	
	

	return 0;
}

I contacted nvidia and they sent me a link to GameWorks on github(i'm a member and all)and githubs gameworks say's nothing about physX lol.

And reading doc's on game works said nothing about having physx in it any where.

I looked at the cPhysx class I created can't see why it would make the compiler generate errors

vc10 express. Can't upgrade have vista only

But anyhow How does the above work.

ph34r.png Ok GameWorks on github does have a link to the Physx SDK, I was to eager, Today the link was there downloaded 3.3.3 PhysX SDK, built the debug binaries and no damn

LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library

rolleyes.gif rolleyes.gifrolleyes.gif

This topic is closed to new replies.

Advertisement