Game Development Community

Newton help....

by Luke Jones · in Torque Game Engine · 05/11/2004 (11:26 pm) · 8 replies

Newton Game Dynamics

Im currently trying to get Newton integrated with Torque, however, the stumbling block is an error to do with linking, a class already being defined.
gameProcess.obj : error LNK2005: "class NWorld nPhysicsWorld" (?nPhysicsWorld@@3VNWorld@@A) already defined in newtonWorld.obj
main.obj : error LNK2005: "class NWorld nPhysicsWorld" (?nPhysicsWorld@@3VNWorld@@A) already defined in newtonWorld.obj
../projects/engine_DEBUG.exe : fatal error LNK1169: one or more multiply defined symbols found

Heres my source files, feel free to mutilate them and point out bad coding.

edit:
The limit on the posts makes a bit hard to post code so I had to split the source, thankfully its small.

in main.cc (around line 353, (bool initGame())
PathManager::init();
   ParticleEngine::init();

   // NEWTON_CHANGE
   nPhysicsWorld.initNewton();
 
   // Execute the main.cs script, the script is not compiled,

Then just below, around line 400 (void shutdownGame())
gServerSceneGraph = NULL;
   gDecalManager = NULL;
   // NEWTON_CHANGE
   nPhysicsWorld.endNewton();

   TerrainRender::shutdown();

and in gameProccess.cc in func
bool ProcessList::advanceServerTime(SimTime timeDelta)
for (; mLastTick != targetTick; mLastTick += TickMs) {
      advanceObjects();
	  // NEWTON_CHANGE // -- only step the simulation on the server
	  nPhysicsWorld.stepNewton();
      }

#1
05/11/2004 (11:28 pm)
NewtonWorld.cpp
#include "game/newton/newtonWorld.h"
#include "newton.h"

#include "console/console.h"
#include "console/consoleTypes.h"
#include "platform/profiler.h"

NewtonMaterials gNewtonMaterials;

NewtonMaterials::NewtonMaterials() {

	defaults.FrictionStatic = 0.8;
	defaults.FrictionKinetic = 0.4;
	defaults.Elasticity = 0.3;
	defaults.Softness = 0.05;

	metal.FrictionStatic = 0.8;
	metal.FrictionKinetic = 0.4;
	metal.Elasticity = 0.3;
	metal.Softness = 0.05;

	dirt.FrictionStatic = 0.8;
	dirt.FrictionKinetic = 0.4;
	dirt.Elasticity = 0.3;
	dirt.Softness = 0.05;

	sand.FrictionStatic = 0.8;
	sand.FrictionKinetic = 0.4;
	sand.Elasticity = 0.3;
	sand.Softness = 0.05;

	wood.FrictionStatic = 0.8;
	wood.FrictionKinetic = 0.4;
	wood.Elasticity = 0.3;
	wood.Softness = 0.05;

	water.FrictionStatic = 0.8;
	water.FrictionKinetic = 0.4;
	water.Elasticity = 0.3;
	water.Softness = 0.05;

	rock.FrictionStatic = 0.8;
	rock.FrictionKinetic = 0.4;
	rock.Elasticity = 0.3;
	rock.Softness = 0.05;
}



void NWorld::initNewton()
{
	NewtonCollision* collision;

	// create the newton world
	nWorld = NewtonCreate(NewtonAlloc, NewtonFree);
//	nWorld = NewtonCreate(NULL, NULL);
	
	m_defaultMaterial = NewtonMaterialGetDefaultGroupID(nWorld);
	m_metalMaterial = NewtonMaterialCreateGroupID(nWorld);
	m_dirtMaterial  = NewtonMaterialCreateGroupID(nWorld);
	m_sandMaterial  = NewtonMaterialCreateGroupID(nWorld);
	m_woodMaterial  = NewtonMaterialCreateGroupID(nWorld);
	m_waterMaterial = NewtonMaterialCreateGroupID(nWorld);
	m_rockMaterial  = NewtonMaterialCreateGroupID(nWorld);

	//console vars
	Con::addVariable("$Newton::defaults::FrictionStatic",TypeF32, &gNewtonMaterials.defaults.FrictionStatic);
	Con::addVariable("$Newton::defaults::FrictionKinetic",TypeF32, &gNewtonMaterials.defaults.FrictionKinetic);
	Con::addVariable("$Newton::defaults::Elasticity",TypeF32, &gNewtonMaterials.defaults.Elasticity);
	Con::addVariable("$Newton::defaults::Softness",TypeF32, &gNewtonMaterials.defaults.Softness);

	Con::addVariable("$Newton::metal::FrictionStatic",TypeF32, &gNewtonMaterials.metal.FrictionStatic);
	Con::addVariable("$Newton::metal::FrictionKinetic",TypeF32, &gNewtonMaterials.metal.FrictionKinetic);
	Con::addVariable("$Newton::metal::Elasticity",TypeF32, &gNewtonMaterials.metal.Elasticity);
	Con::addVariable("$Newton::metal::Softness",TypeF32, &gNewtonMaterials.metal.Softness);

	Con::addVariable("$Newton::dirt::FrictionStatic",TypeF32, &gNewtonMaterials.dirt.FrictionStatic);
	Con::addVariable("$Newton::dirt::FrictionKinetic",TypeF32, &gNewtonMaterials.dirt.FrictionKinetic);
	Con::addVariable("$Newton::dirt::Elasticity",TypeF32, &gNewtonMaterials.dirt.Elasticity);
	Con::addVariable("$Newton::dirt::Softness",TypeF32, &gNewtonMaterials.dirt.Softness);

	Con::addVariable("$Newton::sand::FrictionStatic",TypeF32, &gNewtonMaterials.sand.FrictionStatic);
	Con::addVariable("$Newton::sand::FrictionKinetic",TypeF32, &gNewtonMaterials.sand.FrictionKinetic);
	Con::addVariable("$Newton::sand::Elasticity",TypeF32, &gNewtonMaterials.sand.Elasticity);
	Con::addVariable("$Newton::sand::Softness",TypeF32, &gNewtonMaterials.sand.Softness);
#2
05/11/2004 (11:29 pm)
NewtonWorld.cpp, part 2
Con::addVariable("$Newton::wood::FrictionStatic",TypeF32, &gNewtonMaterials.wood.FrictionStatic);
	Con::addVariable("$Newton::wood::FrictionKinetic",TypeF32, &gNewtonMaterials.wood.FrictionKinetic);
	Con::addVariable("$Newton::wood::Elasticity",TypeF32, &gNewtonMaterials.wood.Elasticity);
	Con::addVariable("$Newton::wood::Softness",TypeF32, &gNewtonMaterials.wood.Softness);

	Con::addVariable("$Newton::water::FrictionStatic",TypeF32, &gNewtonMaterials.water.FrictionStatic);
	Con::addVariable("$Newton::water::FrictionKinetic",TypeF32, &gNewtonMaterials.water.FrictionKinetic);
	Con::addVariable("$Newton::water::Elasticity",TypeF32, &gNewtonMaterials.water.Elasticity);
	Con::addVariable("$Newton::water::Softness",TypeF32, &gNewtonMaterials.water.Softness);

	Con::addVariable("$Newton::rock::FrictionStatic",TypeF32, &gNewtonMaterials.rock.FrictionStatic);
	Con::addVariable("$Newton::rock::FrictionKinetic",TypeF32, &gNewtonMaterials.rock.FrictionKinetic);
	Con::addVariable("$Newton::rock::Elasticity",TypeF32, &gNewtonMaterials.rock.Elasticity);
	Con::addVariable("$Newton::rock::Softness",TypeF32, &gNewtonMaterials.rock.Softness);

	// Set up default material properties for newton
	int i = NewtonMaterialGetDefaultGroupID(nWorld);
	NewtonMaterialSetDefaultFriction   (nWorld, i, i, 
										gNewtonMaterials.defaults.FrictionStatic, 
										gNewtonMaterials.defaults.FrictionKinetic);
	NewtonMaterialSetDefaultElasticity (nWorld, i, i, gNewtonMaterials.defaults.Elasticity);
	NewtonMaterialSetDefaultSoftness   (nWorld, i, i, gNewtonMaterials.defaults.Softness);
	NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL);

	NewtonMaterialSetDefaultFriction   (nWorld, m_metalMaterial, m_metalMaterial, 
										gNewtonMaterials.metal.FrictionStatic, 
										gNewtonMaterials.metal.FrictionKinetic);
	NewtonMaterialSetDefaultElasticity (nWorld, m_metalMaterial, m_metalMaterial, 
										gNewtonMaterials.metal.Elasticity);
	NewtonMaterialSetDefaultSoftness   (nWorld, m_metalMaterial, m_metalMaterial, 
										gNewtonMaterials.metal.Softness);
	//NewtonMaterialSetCollisionCallback (nWorld, m_metalMaterial, m_metalMaterial, &metal_metal, BeginContact, ProcesContact, FinishContact);

	NewtonMaterialSetDefaultFriction   (nWorld, m_dirtMaterial, m_dirtMaterial, 
										gNewtonMaterials.dirt.FrictionStatic, 
										gNewtonMaterials.dirt.FrictionKinetic);
	NewtonMaterialSetDefaultElasticity (nWorld, m_dirtMaterial, m_dirtMaterial, 
										gNewtonMaterials.dirt.Elasticity);
	NewtonMaterialSetDefaultSoftness   (nWorld, m_dirtMaterial, m_dirtMaterial, 
										gNewtonMaterials.dirt.Softness);
	//NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL);
	
}

void NWorld::stepNewton()
{
	NewtonUpdate(nWorld, 0.01f);
} 

void* NWorld::NewtonAlloc (int sizeInBytes)
{
	return new char[sizeInBytes];
}
void NWorld::NewtonFree (void *ptr, int sizeInBytes)
{
	char *tmp;
	tmp = (char*) ptr;
	delete[] tmp;
}

void NWorld::endNewton()
{
	// release the collision tree
	//NewtonReleaseCollision(nWorld, g_newtonmap);
	// release the box primitives
	//for (int i=0; icollision);
	// destroy the Newton world
	NewtonDestroy (nWorld);
}
#3
05/11/2004 (11:29 pm)
NewtonWorld.h
#ifndef NEWTON_WORLD
#define NEWTON_WORLD

#include "newton.h"
#include <math/mPoint.h>

	struct NewtonMaterialParams {
	friend class NWorld;
	friend class NewtonMaterials;
	private:
		F32 FrictionStatic;
		F32 FrictionKinetic;
		F32 Elasticity;
		F32 Softness;
	};

	struct NewtonMaterials {
	friend class NWorld;
	friend class NewtonMaterials;
	private:
		NewtonMaterialParams defaults;
		NewtonMaterialParams metal;
		NewtonMaterialParams dirt;
		NewtonMaterialParams sand;
		NewtonMaterialParams wood;
		NewtonMaterialParams water;
		NewtonMaterialParams rock;
		public:
		NewtonMaterials::NewtonMaterials();
	};

	extern NewtonMaterials gNewtonMaterials;

class NWorld {
public:
	// Newton vars
	NewtonWorld *nWorld;
	// Newton allocation callbacks
	static void* _cdecl NewtonAlloc (int sizeInBytes);
	static void _cdecl NewtonFree (void *ptr, int sizeInBytes);
//public:
	void initNewton ();
	void stepNewton();
	void endNewton();

	int m_defaultMaterial;
	int m_metalMaterial;
	int m_dirtMaterial;
	int m_sandMaterial;
	int m_woodMaterial;
	int m_waterMaterial;
	int m_rockMaterial;
}nPhysicsWorld;

   //NWorld nPhysicsWorld;
   //class NWorld nPhysicsWorld;

#endif
#4
05/13/2004 (11:08 pm)
Damn... I thought at least one person might have something to say, but apparently not, not even a word of wisdom....
#5
05/14/2004 (12:34 am)
I'm not sure about this, but it seems like you declared NWorld twice, at least that's what the message says. I don't think this error comes from the NewtonWorld-files but from gameProcess.h which might contain an additional declaration of NWorld.
#6
05/14/2004 (1:21 am)
That dosnt seem to be it since both main & gameproccess call functions from newtonworld...

the only other way is to declare an instance of NWorld class before using each function in other files (like initNewton, endNewton).

But that dosnt seem like the right way to do it...
#7
05/14/2004 (3:17 am)
NPhysicsWorld is an instance of NWorld and it gets defined every time you include this file. Either make it an extern or a static member of your NWorld class like a singleton. The key is that the object (instance) itself is defined directly in an object file (.cpp/.cc) and not in a header which can then get the object defined in any .cpp/.cc file which includes it which is what's happening right now.

So you'd do something like:
// in NetwonWorld.h
class NWorld
{
	// ... rest of your definitions not shown ...
public:
	static NWorld* getWorld();
};

// in NetwonWorld.cpp
NWorld* NWorld::getWorld()
{
	static NWorld _world;
	return &_world;
}

// in some function
NWorld *world = NWorld::getWorld();
world->initNewton();

Otherwise just use the extern system you're already using for your gNewtonMaterials.
#8
05/14/2004 (3:45 am)
I seriously dont know why I didnt bother to make it an extern...
Problem solved, thanks, just proves a set of fresh eyes helps.

Feel free to use the code and improve it people....