Merge branch 'physicsaedra3' of https://github.com/jhooks1/openmw.git into objectRotationScaling

actorid
gugus 13 years ago
commit 5397b9dba6

@ -115,10 +115,14 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>();
assert (ref->base != NULL);
std::string headID = ref->base->head;
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
@ -126,7 +130,8 @@ namespace MWClass
std::string smodel = "meshes\\base_anim.nif";
if(beast)
smodel = "meshes\\base_animkna.nif";
physics.insertActorPhysics(ptr, smodel);
physics.insertActorPhysics(ptr, smodel);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}

@ -165,8 +165,6 @@ namespace MWWorld
iter!=actors.end(); ++iter)
{
OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first);
//if(iter->first == "player")
// std::cout << "This is player\n";
//dirty stuff to get the camera orientation. Must be changed!
Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first);
@ -176,46 +174,28 @@ namespace MWWorld
Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
// unused
//Ogre::Quaternion both = yawQuat * pitchQuat;
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
playerphysics->ps.viewangles.z = 0;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
if(mFreeFly)
{
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x;
pm_ref.forwardmove = dir1.z;
pm_ref.upmove = dir1.y;
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
dir = 0.07*(yawQuat*pitchQuat*dir1);
}
else
{
Ogre::Quaternion quat = yawNode->getOrientation();
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x;
pm_ref.forwardmove = dir1.z;
pm_ref.upmove = dir1.y;
pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z;
dir = 0.025*(quat*dir1);
}
//set the walk direction
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
}
mEngine->stepSimulation(dt);
}
@ -233,10 +213,6 @@ namespace MWWorld
if(it->first == "player"){
coord = playerphysics->ps.origin;
//std::cout << "ZCoord: " << coord.z << "\n";
//std::cout << "Coord" << coord << "\n";
//coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y
}

@ -73,14 +73,16 @@ class DirArchive: public Ogre::FileSystemArchive
{
{
String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
copy = passed;
}
@ -226,14 +228,16 @@ public:
BSAFile *narc = (BSAFile*)&arc;
String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
// Open the file
StreamPtr strm = narc->getFile(passed.c_str());
@ -248,14 +252,16 @@ bool exists(const String& filename) {
// Check if the file exists.
bool cexists(const String& filename) const {
String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
return arc.exists(passed.c_str());
}

@ -1,4 +1,4 @@
/*
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com >
@ -51,19 +51,64 @@ using namespace Mangle::VFS;
using namespace NifBullet;
// Helper math functions. Reinventing linear algebra for the win!
// Computes B = AxB (matrix*matrix)
static void matrixMul(const Matrix &A, Matrix &B)
{
for (int i=0;i<3;i++)
{
float a = B.v[0].array[i];
float b = B.v[1].array[i];
float c = B.v[2].array[i];
B.v[0].array[i] = a*A.v[0].array[0] + b*A.v[0].array[1] + c*A.v[0].array[2];
B.v[1].array[i] = a*A.v[1].array[0] + b*A.v[1].array[1] + c*A.v[1].array[2];
B.v[2].array[i] = a*A.v[2].array[0] + b*A.v[2].array[1] + c*A.v[2].array[2];
}
}
// Computes C = B + AxC*scale
static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale)
{
// Keep the original values
float a = C[0];
float b = C[1];
float c = C[2];
// Perform matrix multiplication, scaling and addition
for (int i=0;i<3;i++)
C[i] = B.array[i] + (a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2])*scale;
}
// Computes B = AxB (matrix*vector)
static void vectorMul(const Matrix &A, float *C)
{
// Keep the original values
float a = C[0];
float b = C[1];
float c = C[2];
// Perform matrix multiplication, scaling and addition
for (int i=0;i<3;i++)
C[i] = a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2];
}
ManualBulletShapeLoader::~ManualBulletShapeLoader()
{
delete vfs;
}
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(const Nif::Transformation* tr)
{
Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2],
tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2],
tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]);
return rot;
}
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
Ogre::Vector3 ManualBulletShapeLoader::getVector(const Nif::Transformation* tr)
{
Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]);
return vect3;
@ -131,15 +176,15 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
bool hasCollisionNode = hasRootCollisionNode(node);
//do a first pass
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,false);
handleNode(node,0,NULL,hasCollisionNode,false,false);
//if collide = false, then it does a second pass which create a shape for raycasting.
if(cShape->collide == false)
{
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,true);
handleNode(node,0,NULL,hasCollisionNode,false,true);
}
cShape->collide = hasCollisionNode&&cShape->collide;
//cShape->collide = hasCollisionNode&&cShape->collide;
struct TriangleMeshShape : public btBvhTriangleMeshShape
{
@ -186,8 +231,9 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
}
void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
{
// Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least.
flags |= node->flags;
@ -221,19 +267,29 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
}
}
//transfo of parents node + curent node
Ogre::Matrix3 finalRot;
Ogre::Vector3 finalPos;
float finalScale;
Nif::Transformation &final = *((Nif::Transformation*)node->trafo);
Ogre::Vector3 nodePos = getVector(&final);
Ogre::Matrix3 nodeRot = getMatrix(&final);
finalPos = nodePos + parentPos;
finalRot = parentRot*nodeRot;
finalScale = final.scale*parentScale;
if (trafo)
{
// Get a non-const reference to the node's data, since we're
// overwriting it. TODO: Is this necessary?
Transformation &final = *((Transformation*)node->trafo);
// For both position and rotation we have that:
// final_vector = old_vector + old_rotation*new_vector*old_scale
vectorMulAdd(trafo->rotation, trafo->pos, final.pos.array, trafo->scale);
vectorMulAdd(trafo->rotation, trafo->velocity, final.velocity.array, trafo->scale);
// Merge the rotations together
matrixMul(trafo->rotation, final.rotation);
// Scalar values are so nice to deal with. Why can't everything
// just be scalar?
final.scale *= trafo->scale;
}
// For NiNodes, loop through children
if (node->recType == Nif::RC_NiNode)
@ -244,14 +300,14 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
{
if (list.has(i))
{
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,isCollisionNode,raycastingOnly);
handleNode(&list[i], flags,node->trafo,hasCollisionNode,isCollisionNode,raycastingOnly);
}
}
}
else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode))
{
cShape->collide = true;
handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,finalRot,finalPos,parentScale,raycastingOnly);
handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,getMatrix(node->trafo),getVector(node->trafo),node->trafo->scale,raycastingOnly);
}
else if(node->recType == Nif::RC_RootCollisionNode)
{
@ -260,7 +316,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
for (int i=0; i<n; i++)
{
if (list.has(i))
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,true,raycastingOnly);
handleNode(&list[i], flags,node->trafo, hasCollisionNode,true,raycastingOnly);
}
}
}
@ -294,15 +350,17 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags
float* vertices = (float*)data->vertices.ptr;
unsigned short* triangles = (unsigned short*)data->triangles.ptr;
const Matrix &rot = shape->trafo->rotation;
const Vector &pos = shape->trafo->pos;
float scale = shape->trafo->scale;
for(unsigned int i=0; i < data->triangles.length; i = i+3)
{
Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
Ogre::Vector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale);
b1 = parentRot * b1 + parentPos;
b2 = parentRot * b2 + parentPos;
b3 = parentRot * b3 + parentPos;
vectorMulAdd(rot, pos, b1.ptr(), scale);
vectorMulAdd(rot, pos, b2.ptr(), scale);
vectorMulAdd(rot, pos, b3.ptr(), scale);
mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
}
}

@ -95,9 +95,9 @@ public:
void load(const std::string &name,const std::string &group);
private:
Ogre::Matrix3 getMatrix(Nif::Transformation* tr);
Ogre::Matrix3 getMatrix(const Nif::Transformation* tr);
Ogre::Vector3 getVector(Nif::Transformation* tr);
Ogre::Vector3 getVector(const Nif::Transformation* tr);
btQuaternion getbtQuat(Ogre::Matrix3 m);
@ -107,10 +107,10 @@ private:
*Parse a node.
*/
void handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly);
const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly);
/**
*Helpler function
*Helper function
*/
bool hasRootCollisionNode(Nif::Node* node);

@ -1294,7 +1294,7 @@ void NIFLoader::loadResource(Resource *resource)
// Look it up
resourceName = mesh->getName();
//std::cout << resourceName << "\n";
if (!vfs->isFile(resourceName))
{

@ -324,11 +324,18 @@ namespace Physic
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
{
char uniqueID[8];
sprintf( uniqueID, "%07.3f", scale );
std::string sid = uniqueID;
std::string outputstring = mesh + uniqueID + "\"|";
//std::cout << "The string" << outputstring << "\n";
//get the shape from the .nif
mShapeLoader->load(mesh,"General");
BulletShapeManager::getSingletonPtr()->load(mesh,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General");
mShapeLoader->load(outputstring,"General");
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
shape->Shape->setLocalScaling(btVector3(scale,scale,scale));
//create the motionState
CMotionState* newMotionState = new CMotionState(this,name);

@ -229,7 +229,7 @@ bool PM_SlideMove( bool gravity )
end = pm->ps.origin + pm->ps.velocity * time_left;
// see if we can make it there
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
@ -274,7 +274,7 @@ bool PM_SlideMove( bool gravity )
{
// pm->ps->velocity += (trace.plane.normal + pm->ps->velocity)
//VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
pm->ps.velocity = (trace.planenormal + pm->ps.velocity);
pm->ps.velocity = trace.planenormal + pm->ps.velocity;
break;
}
}
@ -298,6 +298,12 @@ bool PM_SlideMove( bool gravity )
if ( into >= 0.1 )
continue; // move doesn't interact with the plane
if(planes[i].x >= .70)
{
pm->ps.velocity = Ogre::Vector3(0,0,0);
return true;
}
// see how hard we are hitting things
if ( -into > pml.impactSpeed )
pml.impactSpeed = -into;
@ -318,6 +324,13 @@ bool PM_SlideMove( bool gravity )
if (clipVelocity.dotProduct(planes[j]) >= 0.1)
//if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 )
continue; // move doesn't interact with the plane
//pm->ps.velocity = Ogre::Vector3(0,0,0);
//return true;
// try clipping the move to the plane
PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
@ -327,8 +340,8 @@ bool PM_SlideMove( bool gravity )
if (clipVelocity.dotProduct(planes[i]) >= 0)
//if ( DotProduct( clipVelocity, planes[i] ) >= 0 )
continue;
// slide the original velocity along the crease
//dProduct (planes[i], planes[j], dir);
dir = planes[i].crossProduct(planes[j]) ;
@ -360,6 +373,7 @@ bool PM_SlideMove( bool gravity )
// see if there is a third plane the the new move enters
for ( k = 0 ; k < numplanes ; k++ )
{
if ( k == i || k == j )
continue;
@ -1457,6 +1471,7 @@ static void PM_GroundTrace( void )
// slopes that are too steep will not be considered onground
//if ( trace.plane.normal[2] < MIN_WALK_NORMAL )
//std::cout << "MinWalkNormal" << trace.planenormal.z;
if (trace.planenormal.z < MIN_WALK_NORMAL)
{
//if ( pm->debugLevel )

@ -41,7 +41,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
#define MAX_GENTITIES (1 << GENTITYNUM_BITS)
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
#define MIN_WALK_NORMAL .7f // can't walk on very steep slopes
#define JUMP_VELOCITY (270)
#define PS_PMOVEFRAMECOUNTBITS 6
#define MINS_Z -24

Loading…
Cancel
Save