From ca9224ed7f8813b2eb9bd4cd70e641308c2d4685 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 21 May 2012 10:58:04 +0200 Subject: [PATCH 01/51] starting scale function --- apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 2 ++ apps/openmw/mwworld/world.cpp | 5 +++++ apps/openmw/mwworld/world.hpp | 2 ++ 4 files changed, 14 insertions(+) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 5fb5038479..f1c50c29a7 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -196,4 +196,9 @@ namespace MWWorld { return ""; } + + void adjustScale(float& x, float& y, float& z) + { + } + } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 513dc942b5..0fc12bfe2b 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -193,6 +193,8 @@ namespace MWWorld virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; ///< @return the enchantment ID if the object is enchanted, otherwise an empty string /// (default implementation: return empty string) + + virtual void adjustScale(float& x, float& y, float& z); }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index eeda92277e..fbbeef154c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -611,6 +611,11 @@ namespace MWWorld mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); } + void World::scaleObject (Ptr ptr, float x, float y, float z) + { + MWWorld::Class::get(ptr).adjustScale(x,y,z); + } + void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const { const int cellSize = 8192; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 49a3cf0296..cb849cc1b4 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -222,6 +222,8 @@ namespace MWWorld void moveObject (Ptr ptr, float x, float y, float z); + void scaleObject (Ptr ptr, float x, float y, float z); + void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; ///< Convert cell numbers to position. From 0066ef9b5491604a34a3fb69d27cbc8e61dab421 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 22 May 2012 21:40:24 -0400 Subject: [PATCH 02/51] Some cleanup --- apps/openmw/mwworld/physicssystem.cpp | 40 ++++++--------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 808c712a07..33024cfdee 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -140,8 +140,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); @@ -151,46 +149,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); } @@ -208,10 +188,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 - } From 51b6d5cae055a6e24fc16f706b2246950052e55b Mon Sep 17 00:00:00 2001 From: gugus Date: Fri, 25 May 2012 18:23:06 +0200 Subject: [PATCH 03/51] Scale *should* work. (no script instruction yet) --- apps/openmw/mwworld/class.cpp | 5 ++++- apps/openmw/mwworld/class.hpp | 4 +++- apps/openmw/mwworld/world.cpp | 16 ++++++++++++++-- apps/openmw/mwworld/world.hpp | 4 +++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 6a67652539..4064a451ae 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -203,8 +203,11 @@ namespace MWWorld return ""; } - void adjustScale(float& x, float& y, float& z) + void Class::adjustScale(const MWWorld::Ptr& ptr,float& scale) const { } + void Class::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const + { + } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 0ed0b0e0d1..a8639daa9d 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -197,7 +197,9 @@ namespace MWWorld ///< @return the enchantment ID if the object is enchanted, otherwise an empty string /// (default implementation: return empty string) - virtual void adjustScale(float& x, float& y, float& z); + virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const; + + virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index c2926c1a3f..6be4a13bac 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -611,9 +611,21 @@ namespace MWWorld mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); } - void World::scaleObject (Ptr ptr, float x, float y, float z) + void World::scaleObject (Ptr ptr, float scale) + { + MWWorld::Class::get(ptr).adjustScale(ptr,scale); + + ptr.getCellRef().scale = scale; + scale = scale/ptr.getRefData().getBaseNode()->getScale().x; + ptr.getRefData().getBaseNode()->setScale(scale,scale,scale); + mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); + /// \todo cell change for non-player ref + + //mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z)); + } + + void World::rotateObject (Ptr ptr,float x,float y,float z) { - MWWorld::Class::get(ptr).adjustScale(x,y,z); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index cc6a665fc1..e684ca39e6 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -222,7 +222,9 @@ namespace MWWorld void moveObject (Ptr ptr, float x, float y, float z); - void scaleObject (Ptr ptr, float x, float y, float z); + void scaleObject (Ptr ptr, float scale); + + void rotateObject (Ptr ptr,float x,float y,float z); void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; ///< Convert cell numbers to position. From 77084b27c07b5948717638d6a8c4f8d93bca9259 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 28 May 2012 16:01:35 +0200 Subject: [PATCH 04/51] some work for rotation/scaling --- apps/openmw/mwscript/statsextensions.cpp | 16 ++++++++++++++++ apps/openmw/mwworld/world.cpp | 10 +++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index d235192817..6e9b1e5835 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -500,6 +500,22 @@ namespace MWScript } }; + template + class OpSetScale : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Float scale = runtime[0].mInteger; + runtime.pop(); + + MWBase::Environment::get().getWorld()->scaleObject(ptr,scale); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 6be4a13bac..2a33325933 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -619,13 +619,17 @@ namespace MWWorld scale = scale/ptr.getRefData().getBaseNode()->getScale().x; ptr.getRefData().getBaseNode()->setScale(scale,scale,scale); mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); - /// \todo cell change for non-player ref - - //mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z)); } void World::rotateObject (Ptr ptr,float x,float y,float z) { + MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); + + ptr.getRefData().getPosition().rot[0] = x; + ptr.getRefData().getPosition().rot[0] = y; + ptr.getRefData().getPosition().rot[0] = z; + //ptr.getRefData().getBaseNode()->rotate(ptr.getRefData().getBaseNode()->get + //mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const From 26d6c9453c3d1d80936189cce56a7eb38a148946 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 29 May 2012 10:15:29 +0200 Subject: [PATCH 05/51] more work on rotation --- apps/openmw/mwworld/world.cpp | 44 ++++++++++++++++++++++++++++++++--- apps/openmw/mwworld/world.hpp | 4 +++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 2a33325933..116710a1e2 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -621,17 +621,55 @@ namespace MWWorld mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); } - void World::rotateObject (Ptr ptr,float x,float y,float z) + void World::rotateObject (Ptr ptr,float x,float y,float z,bool WorldAxis) { MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); - ptr.getRefData().getPosition().rot[0] = x; + /*ptr.getRefData().getPosition().rot[0] = x; ptr.getRefData().getPosition().rot[0] = y; - ptr.getRefData().getPosition().rot[0] = z; + ptr.getRefData().getPosition().rot[0] = z;*/ + if(WorldAxis) + { + ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(x)); + ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(y)); + ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(z)); + } + else + { + Ogre::Matrix3 axis = ptr.getRefData().getBaseNode()->getLocalAxes(); + Ogre::Vector3 xAxis = axis.GetColumn(0); + Ogre::Vector3 yAxis = axis.GetColumn(1); + Ogre::Vector3 zAxis = axis.GetColumn(2); + ptr.getRefData().getBaseNode()->rotate(xAxis,Ogre::Degree(x)); + ptr.getRefData().getBaseNode()->rotate(yAxis,Ogre::Degree(y)); + ptr.getRefData().getBaseNode()->rotate(zAxis,Ogre::Degree(z)); + } + Ogre::Matrix3 rot; + ptr.getRefData().getBaseNode()->getOrientation().ToRotationMatrix(rot); + Ogre::Radian rx,ry,rz; + rot.ToEulerAnglesXYZ(rx,ry,rz); + + ptr.getRefData().getPosition().rot[0] = rx.valueRadians(); + ptr.getRefData().getPosition().rot[0] = ry.valueRadians(); + ptr.getRefData().getPosition().rot[0] = rz.valueRadians(); //ptr.getRefData().getBaseNode()->rotate(ptr.getRefData().getBaseNode()->get //mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); } + void setObjectRotation (Ptr ptr,float x,float y,float z) + { + MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); + + ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians(); + ptr.getRefData().getPosition().rot[0] = Ogre::Degree(y).valueRadians(); + ptr.getRefData().getPosition().rot[0] = Ogre::Degree(z).valueRadians(); + + Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X); + Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); + Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); + ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); + } + void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const { const int cellSize = 8192; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index e684ca39e6..6f810e9766 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -224,7 +224,9 @@ namespace MWWorld void scaleObject (Ptr ptr, float scale); - void rotateObject (Ptr ptr,float x,float y,float z); + void rotateObject (Ptr ptr,float x,float y,float z,bool WorldAxis); + + void setObjectRotation (Ptr ptr,float x,float y,float z); void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; ///< Convert cell numbers to position. From d8051095d669c552123f4662ea501c9cd021e6bd Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 29 May 2012 10:36:12 +0200 Subject: [PATCH 06/51] rotation are updated in the physis system --- apps/openmw/mwworld/physicssystem.cpp | 13 +++++++++++-- apps/openmw/mwworld/world.cpp | 8 ++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 808c712a07..c4e34a5407 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -288,17 +288,26 @@ namespace MWWorld void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) { - if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); } + if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) + { + body->setWorldTransform(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),body->getWorldTransform().getOrigin())); + } } void PhysicsSystem::scaleObject (const std::string& handle, float scale) { - + if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) + { + // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + // start positions others than 0, 0, 0 + //body->setWorldTransform(btTransform().se + } } bool PhysicsSystem::toggleCollisionMode() diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 116710a1e2..69da980967 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -625,9 +625,6 @@ namespace MWWorld { MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); - /*ptr.getRefData().getPosition().rot[0] = x; - ptr.getRefData().getPosition().rot[0] = y; - ptr.getRefData().getPosition().rot[0] = z;*/ if(WorldAxis) { ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(x)); @@ -652,11 +649,13 @@ namespace MWWorld ptr.getRefData().getPosition().rot[0] = rx.valueRadians(); ptr.getRefData().getPosition().rot[0] = ry.valueRadians(); ptr.getRefData().getPosition().rot[0] = rz.valueRadians(); + + mPhysics->rotateObject(Class::get(ptr).getId(ptr),ptr.getRefData().getBaseNode()->getOrientation()); //ptr.getRefData().getBaseNode()->rotate(ptr.getRefData().getBaseNode()->get //mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); } - void setObjectRotation (Ptr ptr,float x,float y,float z) + void World::setObjectRotation (Ptr ptr,float x,float y,float z) { MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); @@ -668,6 +667,7 @@ namespace MWWorld Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); + mPhysics->rotateObject(Class::get(ptr).getId(ptr),ptr.getRefData().getBaseNode()->getOrientation()); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const From f83ffecae5cf5433069f355f5d41b3c87386c845 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 29 May 2012 15:57:13 +0200 Subject: [PATCH 07/51] SetAngle and SetScale script instruction --- apps/openmw/mwscript/docs/vmformat.txt | 4 ++- apps/openmw/mwscript/statsextensions.cpp | 38 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 0920c72f8e..bb8f8a214e 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -146,4 +146,6 @@ op 0x200014f: ForceGreeting op 0x2000150: ForceGreeting, explicit reference op 0x2000151: ToggleFullHelp op 0x2000152: Goodbye -opcodes 0x2000153-0x3ffffff unused +op 0x2000153: SetScale +op 0x2000154: SetAngle +opcodes 0x2000155-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 6e9b1e5835..c68febec3a 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -516,6 +516,35 @@ namespace MWScript } }; + template + class OpSetAngle : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float angle = runtime[0].mInteger; + runtime.pop(); + + if(axis == "X") + { + MWBase::Environment::get().getWorld()->setObjectRotation(ptr,angle,0,0); + } + if(axis == "Y") + { + MWBase::Environment::get().getWorld()->setObjectRotation(ptr,0,angle,0); + } + if(axis == "Z") + { + MWBase::Environment::get().getWorld()->setObjectRotation(ptr,0,0,angle); + } + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -562,6 +591,9 @@ namespace MWScript const int opcodeModDisposition = 0x200014d; const int opcodeModDispositionExplicit = 0x200014e; + const int opcodeSetScale = 0x2000153; + const int opcodeSetAngle = 0x2000154; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -644,6 +676,9 @@ namespace MWScript extensions.registerInstruction("moddisposition","l",opcodeModDisposition, opcodeModDispositionExplicit); extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); + + extensions.registerInstruction("setscale","/l",opcodeSetScale); + extensions.registerInstruction("setangle","/Sl",opcodeSetAngle); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -715,6 +750,9 @@ namespace MWScript interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank); interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); + + interpreter.installSegment5(opcodeSetScale,new OpSetScale); + interpreter.installSegment5(opcodeSetAngle,new OpSetAngle); } } } From a711a3ebe1b67886a58b004ddc13e5bbfc446fa2 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 29 May 2012 16:45:43 +0200 Subject: [PATCH 08/51] Various fixes --- apps/openmw/mwscript/docs/vmformat.txt | 4 +++- apps/openmw/mwscript/statsextensions.cpp | 10 +++++++--- apps/openmw/mwworld/physicssystem.cpp | 4 ---- apps/openmw/mwworld/world.cpp | 1 + libs/openengine/bullet/physic.cpp | 24 ++++++++++++++++++++---- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index bb8f8a214e..86cf73117b 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -147,5 +147,7 @@ op 0x2000150: ForceGreeting, explicit reference op 0x2000151: ToggleFullHelp op 0x2000152: Goodbye op 0x2000153: SetScale -op 0x2000154: SetAngle +op 0x2000154: SetScale, explicit reference +op 0x2000155: SetAngle +op 0x2000156: SetAngle, explicit reference opcodes 0x2000155-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index c68febec3a..83bfacf40c 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -592,7 +592,9 @@ namespace MWScript const int opcodeModDispositionExplicit = 0x200014e; const int opcodeSetScale = 0x2000153; - const int opcodeSetAngle = 0x2000154; + const int opcodeSetScaleExplicit = 0x2000154; + const int opcodeSetAngle = 0x2000155; + const int opcodeSetAngleExplicit = 0x2000156; void registerExtensions (Compiler::Extensions& extensions) { @@ -677,8 +679,8 @@ namespace MWScript opcodeModDispositionExplicit); extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); - extensions.registerInstruction("setscale","/l",opcodeSetScale); - extensions.registerInstruction("setangle","/Sl",opcodeSetAngle); + extensions.registerInstruction("setscale","l",opcodeSetScale,opcodeSetScaleExplicit); + extensions.registerInstruction("setangle","Sl",opcodeSetAngle,opcodeSetAngleExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -752,7 +754,9 @@ namespace MWScript interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); interpreter.installSegment5(opcodeSetScale,new OpSetScale); + interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale); interpreter.installSegment5(opcodeSetAngle,new OpSetAngle); + interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle); } } } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index c4e34a5407..8ebdf2981e 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -290,8 +290,6 @@ namespace MWWorld { if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); } if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) @@ -304,8 +302,6 @@ namespace MWWorld { if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 //body->setWorldTransform(btTransform().se } } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 69da980967..db96b6a194 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -668,6 +668,7 @@ namespace MWWorld Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); mPhysics->rotateObject(Class::get(ptr).getId(ptr),ptr.getRefData().getBaseNode()->getOrientation()); + std::cout << Class::get(ptr).getId(ptr); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index d30d5e9f13..4ead88994c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -392,8 +392,16 @@ namespace Physic RigidBody* PhysicEngine::getRigidBody(std::string name) { - RigidBody* body = RigidBodyMap[name]; - return body; + RigidBodyContainer::iterator it = RigidBodyMap.find(name); + if (it != RigidBodyMap.end() ) + { + RigidBody* body = RigidBodyMap[name]; + return body; + } + else + { + return 0; + } } void PhysicEngine::stepSimulation(double deltaT) @@ -450,8 +458,16 @@ namespace Physic PhysicActor* PhysicEngine::getCharacter(std::string name) { - PhysicActor* act = PhysicActorMap[name]; - return act; + PhysicActorContainer::iterator it = PhysicActorMap.find(name); + if (it != PhysicActorMap.end() ) + { + PhysicActor* act = PhysicActorMap[name]; + return act; + } + else + { + return 0; + } } void PhysicEngine::emptyEventLists(void) From fb4e7f02b9c7305d0d6140b193fd0c21b152ed8b Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 29 May 2012 22:03:00 -0400 Subject: [PATCH 09/51] code correction --- apps/openmw/mwclass/npc.cpp | 6 +++--- libs/openengine/bullet/pmove.cpp | 8 +++++--- libs/openengine/bullet/pmove.h | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e7f6cc5270..b1d61a4ede 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -119,7 +119,7 @@ namespace MWClass void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { - + ESMS::LiveCellRef *ref = ptr.get(); @@ -128,12 +128,12 @@ namespace MWClass 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_"; - + std::string smodel = "meshes\\base_anim.nif"; if(beast) smodel = "meshes\\base_animkna.nif"; - physics.insertActorPhysics(ptr, smodel); + physics.insertObjectPhysics(ptr, smodel); } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 591f1869f8..cdeb557baa 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -232,7 +232,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); @@ -277,7 +277,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; } } @@ -330,7 +330,7 @@ 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); @@ -363,6 +363,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; @@ -1460,6 +1461,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 ) diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index e46eb9d2e7..6e67db711b 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -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 @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) + playerStruct() : gravity(800.0f), speed(500.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From d081f7ea83d55f1941f3bc953a0c44457afc5f6f Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 31 May 2012 20:13:40 -0400 Subject: [PATCH 10/51] Don't run up walls --- libs/openengine/bullet/pmove.cpp | 15 ++++++++++++++- libs/openengine/bullet/pmove.h | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index cdeb557baa..1fc394259b 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -301,6 +301,12 @@ bool PM_SlideMove( bool gravity ) if ( into >= 0.1 ) continue; // move doesn't interact with the plane + std::cout << "Second plane" << planes[i] << "\n"; + 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; @@ -321,6 +327,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 ); @@ -330,8 +343,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]) ; diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 6e67db711b..d48bd36377 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(500.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) + playerStruct() : gravity(800.0f), speed(2000.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From 4ff36a9018834f35fa034594d76d47bfc86d2ea1 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 6 Jun 2012 16:29:44 -0400 Subject: [PATCH 11/51] Bullet loader trafos changed to match NIFLoader --- components/nifbullet/bullet_nif_loader.cpp | 97 +++++++++++++++++----- components/nifbullet/bullet_nif_loader.hpp | 8 +- 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 30cb4562d0..153c529345 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -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; @@ -88,6 +133,7 @@ btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v) void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) { + std::cout << "Beginning physics\n"; cShape = static_cast(resource); resourceName = cShape->getName(); cShape->collide = false; @@ -131,12 +177,12 @@ 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; @@ -157,6 +203,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) currentShape = new TriangleMeshShape(mTriMesh,true); cShape->Shape = currentShape; + std::cout << "End bullet physics\n"; } bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) @@ -186,8 +233,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) { + std::cout << "Handle Node\n"; // Accumulate the flags from all the child nodes. This works for all // the flags we currently use, at least. flags |= node->flags; @@ -221,19 +269,30 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, } } - //transfo of parents node + curent node - Ogre::Matrix3 finalRot; - Ogre::Vector3 finalPos; - float finalScale; + + + if (trafo) + { + std::cout << "Before trafo\n"; + // Get a non-const reference to the node's data, since we're + // overwriting it. TODO: Is this necessary? + Transformation &final = *((Transformation*)node->trafo); - Nif::Transformation &final = *((Nif::Transformation*)node->trafo); - Ogre::Vector3 nodePos = getVector(&final); - Ogre::Matrix3 nodeRot = getMatrix(&final); + // 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); - finalPos = nodePos + parentPos; - finalRot = parentRot*nodeRot; - finalScale = final.scale*parentScale; + // 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; + std::cout << "After Trafo\n"; + } + + std::cout << "After Trafo2\n"; // For NiNodes, loop through children if (node->recType == Nif::RC_NiNode) @@ -244,14 +303,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(node), flags,finalRot,finalPos,parentScale,raycastingOnly); + handleNiTriShape(dynamic_cast(node), flags,getMatrix(node->trafo),getVector(node->trafo),node->trafo->scale,raycastingOnly); } else if(node->recType == Nif::RC_RootCollisionNode) { @@ -260,7 +319,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, for (int i=0; itrafo, hasCollisionNode,true,raycastingOnly); } } } diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index ed3aceac46..488a7a42b0 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -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); From fb0a52809dd1da3ef953728be2200a633bb383bf Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 9 Jun 2012 15:19:15 -0400 Subject: [PATCH 12/51] Changing transformation processing --- apps/openmw/mwclass/npc.cpp | 2 +- components/nifbullet/bullet_nif_loader.cpp | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index b1d61a4ede..0a1a750f79 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -133,7 +133,7 @@ namespace MWClass std::string smodel = "meshes\\base_anim.nif"; if(beast) smodel = "meshes\\base_animkna.nif"; - physics.insertObjectPhysics(ptr, smodel); + physics.insertActorPhysics(ptr, smodel); } diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 153c529345..e87d5624e9 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -185,7 +185,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) handleNode(node,0,NULL,hasCollisionNode,false,true); } - cShape->collide = hasCollisionNode&&cShape->collide; + //cShape->collide = hasCollisionNode&&cShape->collide; struct TriangleMeshShape : public btBvhTriangleMeshShape { @@ -353,15 +353,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)); } } From 595b0729da99bf9a9d2d06f2a28eedbcacb9832e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 10 Jun 2012 21:08:58 -0400 Subject: [PATCH 13/51] Few things changed --- apps/openmw/mwclass/creature.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 2 +- components/nifbullet/bullet_nif_loader.cpp | 9 +++------ libs/openengine/bullet/pmove.cpp | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 653fabd089..150cb40922 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -85,7 +85,7 @@ namespace MWClass const std::string &model = ref->base->model; assert (ref->base != NULL); if(!model.empty()){ - physics.insertActorPhysics(ptr, "meshes\\" + model); + physics.insertObjectPhysics(ptr, "meshes\\" + model); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0a1a750f79..656e6d4447 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -133,7 +133,7 @@ namespace MWClass std::string smodel = "meshes\\base_anim.nif"; if(beast) smodel = "meshes\\base_animkna.nif"; - physics.insertActorPhysics(ptr, smodel); + //physics.insertObjectPhysics(ptr, smodel); } diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index e87d5624e9..17c5f18aca 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -133,7 +133,6 @@ btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v) void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) { - std::cout << "Beginning physics\n"; cShape = static_cast(resource); resourceName = cShape->getName(); cShape->collide = false; @@ -203,7 +202,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) currentShape = new TriangleMeshShape(mTriMesh,true); cShape->Shape = currentShape; - std::cout << "End bullet physics\n"; } bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) @@ -235,7 +233,7 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) { - std::cout << "Handle Node\n"; + // Accumulate the flags from all the child nodes. This works for all // the flags we currently use, at least. flags |= node->flags; @@ -273,7 +271,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, if (trafo) { - std::cout << "Before trafo\n"; + // Get a non-const reference to the node's data, since we're // overwriting it. TODO: Is this necessary? Transformation &final = *((Transformation*)node->trafo); @@ -289,10 +287,9 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, // Scalar values are so nice to deal with. Why can't everything // just be scalar? final.scale *= trafo->scale; - std::cout << "After Trafo\n"; + } - std::cout << "After Trafo2\n"; // For NiNodes, loop through children if (node->recType == Nif::RC_NiNode) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 1fc394259b..ae160365b3 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -301,7 +301,7 @@ bool PM_SlideMove( bool gravity ) if ( into >= 0.1 ) continue; // move doesn't interact with the plane - std::cout << "Second plane" << planes[i] << "\n"; + if(planes[i].x >= .70) { pm->ps.velocity = Ogre::Vector3(0,0,0); From b14c132a31bc9b8f410647b502a570b92b5c6608 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 11 Jun 2012 13:25:06 -0400 Subject: [PATCH 14/51] Merging in the latest master --- apps/openmw/mwgui/settingswindow.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index ce95edbd2e..e3827c7b03 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -16,10 +16,10 @@ namespace MWGui SettingsWindow(WindowManager& parWindowManager); private: - static const float sFovMin = 30; - static const float sFovMax = 140; - static const float sViewDistMin = 2000; - static const float sViewDistMax = 5600; + static int const sFovMin = 30; + static int const sFovMax = 140; + static int const sViewDistMin = 2000; + static int const sViewDistMax = 5600; protected: MyGUI::Button* mOkButton; From 10810ee3115c2414500bb914c07f533a57dcd6fb Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 11 Jun 2012 19:55:10 -0400 Subject: [PATCH 15/51] Outputting formatted string with scale --- libs/openengine/bullet/physic.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index a94434e5b5..c33d106cd8 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -324,11 +324,18 @@ namespace Physic RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) { + char uniqueID[4]; + sprintf( uniqueID, "%1.2f", scale ); + std::string sid = uniqueID; + std::string outputstring = mesh + sid + ">|"; + std::cout << outputstring << "\n"; + //get the shape from the .nif mShapeLoader->load(mesh,"General"); BulletShapeManager::getSingletonPtr()->load(mesh,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General"); shape->Shape->setLocalScaling(btVector3(scale,scale,scale)); + //create the motionState CMotionState* newMotionState = new CMotionState(this,name); From 5028f9926d6724f6b89aee5eb9fd330554f6d2c8 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 12 Jun 2012 18:09:58 -0400 Subject: [PATCH 16/51] Bullet scale solution --- components/nifogre/ogre_nif_loader.cpp | 2 +- libs/openengine/bullet/physic.cpp | 7 +++---- libs/openengine/bullet/pmove.h | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 331701c2a4..669ef584fa 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -1294,7 +1294,7 @@ void NIFLoader::loadResource(Resource *resource) // Look it up resourceName = mesh->getName(); - //std::cout << resourceName << "\n"; + if (!vfs->isFile(resourceName)) { diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index c33d106cd8..0cacd67a84 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -328,12 +328,11 @@ namespace Physic sprintf( uniqueID, "%1.2f", scale ); std::string sid = uniqueID; std::string outputstring = mesh + sid + ">|"; - std::cout << 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)); diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index d48bd36377..f368f05f64 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(2000.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) + playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From 897a331244443f03a21fc0ca45c6788f48cc18c5 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 13 Jun 2012 12:21:51 -0400 Subject: [PATCH 17/51] NPC activation --- apps/openmw/mwclass/creature.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 86fd1fe23d..e33fd322a7 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -84,7 +84,7 @@ namespace MWClass const std::string &model = ref->base->model; assert (ref->base != NULL); if(!model.empty()){ - physics.insertObjectPhysics(ptr, "meshes\\" + model); + physics.insertActorPhysics(ptr, "meshes\\" + model); } MWBase::Environment::get().getMechanicsManager()->addActor (ptr); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a3c20840af..8062dc35ee 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -130,7 +130,7 @@ namespace MWClass std::string smodel = "meshes\\base_anim.nif"; if(beast) smodel = "meshes\\base_animkna.nif"; - + physics.insertActorPhysics(ptr, smodel); MWBase::Environment::get().getMechanicsManager()->addActor (ptr); From c4c8288af8d51f01f22df3813a6b01b8f0e76a14 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 13 Jun 2012 19:34:13 -0400 Subject: [PATCH 18/51] Seven digit scales --- components/bsa/bsa_archive.cpp | 36 ++++++++++++++++++------------- libs/openengine/bullet/physic.cpp | 7 +++--- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index d3b75d4ae4..e9ce3f6150 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -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()); } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 0cacd67a84..d075536d2b 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -324,10 +324,11 @@ namespace Physic RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) { - char uniqueID[4]; - sprintf( uniqueID, "%1.2f", scale ); + char uniqueID[8]; + sprintf( uniqueID, "%07.3f", scale ); std::string sid = uniqueID; - std::string outputstring = mesh + sid + ">|"; + std::string outputstring = mesh + uniqueID + "\"|"; + //std::cout << "The string" << outputstring << "\n"; //get the shape from the .nif mShapeLoader->load(outputstring,"General"); From a1902b4121ba7da31ea9cbfbd7181315642178ea Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 16 Jun 2012 17:29:03 -0400 Subject: [PATCH 19/51] Tweaks for high speed --- libs/openengine/bullet/pmove.cpp | 10 ++++++++++ libs/openengine/bullet/pmove.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index ae160365b3..b6876e43fb 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -861,6 +861,8 @@ static void PM_WalkMove( playerMove* const pmove ) float accelerate; float vel; //pm->ps.gravity = 4000; + + //std::cout << "Player is walking\n"; if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) @@ -1162,6 +1164,11 @@ void PM_GroundTraceMissed() { traceResults trace; Ogre::Vector3 point; + //We should not have significant upwards velocity when in the air, unless we jumped. + //This code protects against flying into the air when moving at high speeds. + //Z velocity is set to 50, instead of 0, to help move up certain steps. + if(pm->ps.velocity.z > 50.0f) + pm->ps.velocity.z = 50.0f; //std::cout << "Ground trace missed\n"; // we just transitioned into freefall //if ( pm->debugLevel ) @@ -1587,8 +1594,11 @@ void PM_AirMove() else PM_SlideMove ( qtrue ); #endif*/ + //std::cout << "Moving in the air" << pm->ps.velocity << "\n"; /*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/; + + } static void PM_NoclipMove( void ) diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index f368f05f64..d838f17f5b 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -28,7 +28,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define MAX_CLIP_PLANES 5 #define OVERCLIP 1.001f //#define STEPSIZE 18 // 18 is way too much -#define STEPSIZE (18 / 2) +#define STEPSIZE (13.5) #ifndef M_PI #define M_PI 3.14159265358979323846f #endif From ac6b455592af49c9e6603a80f8fb2991ad61a3f3 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 17 Jun 2012 12:57:59 -0400 Subject: [PATCH 20/51] StepSize moved back to 9 --- libs/openengine/bullet/pmove.cpp | 8 +++++--- libs/openengine/bullet/pmove.h | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index b6876e43fb..6173acacfc 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -530,7 +530,7 @@ int PM_StepSlideMove( bool gravity ) delta = pm->ps.origin.z - start_o.z; if ( delta > 2 ) { - pm->ps.counter = 10; + pm->ps.counter = 5; /* if (gravity) @@ -1167,8 +1167,7 @@ void PM_GroundTraceMissed() //We should not have significant upwards velocity when in the air, unless we jumped. //This code protects against flying into the air when moving at high speeds. //Z velocity is set to 50, instead of 0, to help move up certain steps. - if(pm->ps.velocity.z > 50.0f) - pm->ps.velocity.z = 50.0f; + //std::cout << "Ground trace missed\n"; // we just transitioned into freefall //if ( pm->debugLevel ) @@ -1431,10 +1430,13 @@ static void PM_GroundTrace( void ) // if the trace didn't hit anything, we are in free fall if ( trace.fraction == 1.0) { + if(pm->ps.velocity.z > 50.0f && pm->ps.bSnap) + pm->ps.velocity.z = 50.0f; if(pm->ps.snappingImplemented){ if(pm->ps.bSnap && pm->ps.counter <= 0) PM_GroundTraceMissed(); } + return; diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index d838f17f5b..bc475a9340 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -28,7 +28,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define MAX_CLIP_PLANES 5 #define OVERCLIP 1.001f //#define STEPSIZE 18 // 18 is way too much -#define STEPSIZE (13.5) +#define STEPSIZE (9) #ifndef M_PI #define M_PI 3.14159265358979323846f #endif @@ -42,7 +42,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define ENTITYNUM_NONE (MAX_GENTITIES - 1) #define ENTITYNUM_WORLD (MAX_GENTITIES - 2) #define MIN_WALK_NORMAL .7f // can't walk on very steep slopes -#define JUMP_VELOCITY (270) +#define JUMP_VELOCITY (540) #define PS_PMOVEFRAMECOUNTBITS 6 #define MINS_Z -24 #define DEFAULT_VIEWHEIGHT 26 @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) + playerStruct() : gravity(800.0f), speed(2000.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From 33fe80723ccda649ed2a1391002cc32489c6d6f2 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 17 Jun 2012 20:56:10 -0400 Subject: [PATCH 21/51] btScaledBvhTriangleMeshShapes --- apps/openmw/mwworld/physicssystem.cpp | 1 + apps/openmw/mwworld/physicssystem.hpp | 1 + libs/openengine/bullet/physic.cpp | 16 ++++++++-------- libs/openengine/bullet/physic.hpp | 1 + libs/openengine/bullet/pmove.cpp | 2 +- libs/openengine/bullet/pmove.h | 4 ++-- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 3757609b20..46b72956d5 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -237,6 +237,7 @@ namespace MWWorld void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh, const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position) { + handleToMesh[handle] = mesh; OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); mEngine->addRigidBody(body); btTransform tr; diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 1a8bd87ae4..b46ce117bf 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -72,6 +72,7 @@ namespace MWWorld OEngine::Physic::PhysicEngine* mEngine; bool mFreeFly; playerMove* playerphysics; + std::map handleToMesh; PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index d075536d2b..6c4e426973 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -324,24 +324,24 @@ namespace Physic RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) { - char uniqueID[8]; + /*char uniqueID[8]; sprintf( uniqueID, "%07.3f", scale ); std::string sid = uniqueID; - std::string outputstring = mesh + uniqueID + "\"|"; + std::string outputstring = mesh + uniqueID + "\"|";*/ //std::cout << "The string" << outputstring << "\n"; //get the shape from the .nif - mShapeLoader->load(outputstring,"General"); - BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); - BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); - shape->Shape->setLocalScaling(btVector3(scale,scale,scale)); - + mShapeLoader->load(mesh,"General"); + BulletShapeManager::getSingletonPtr()->load(mesh,"General"); + BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General"); + //shape->Shape->setLocalScaling(); + btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast (shape->Shape), btVector3(scale,scale,scale)); //create the motionState CMotionState* newMotionState = new CMotionState(this,name); //create the real body - btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); + btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,scaled); RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; return body; diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 8115723201..8a3295ec36 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -7,6 +7,7 @@ #include #include #include "BulletShapeLoader.h" +#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" class btRigidBody; class btBroadphaseInterface; diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 6173acacfc..fa87e90406 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -1430,7 +1430,7 @@ static void PM_GroundTrace( void ) // if the trace didn't hit anything, we are in free fall if ( trace.fraction == 1.0) { - if(pm->ps.velocity.z > 50.0f && pm->ps.bSnap) + if(pm->ps.velocity.z > 50.0f && pm->ps.bSnap && pm->ps.speed > 1000.0f) pm->ps.velocity.z = 50.0f; if(pm->ps.snappingImplemented){ if(pm->ps.bSnap && pm->ps.counter <= 0) diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index bc475a9340..592ca724d2 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -42,7 +42,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define ENTITYNUM_NONE (MAX_GENTITIES - 1) #define ENTITYNUM_WORLD (MAX_GENTITIES - 2) #define MIN_WALK_NORMAL .7f // can't walk on very steep slopes -#define JUMP_VELOCITY (540) +#define JUMP_VELOCITY (270) #define PS_PMOVEFRAMECOUNTBITS 6 #define MINS_Z -24 #define DEFAULT_VIEWHEIGHT 26 @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(2000.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) + playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From 4d55ecfdbed5c09c21e7ea7bb59c675f3b007203 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 18 Jun 2012 13:03:00 -0400 Subject: [PATCH 22/51] Deleting scaled shapes; scaleObject() --- apps/openmw/mwworld/physicssystem.cpp | 10 +++++++++- libs/openengine/bullet/physic.cpp | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 46b72956d5..530881ec92 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -300,7 +300,15 @@ namespace MWWorld void PhysicsSystem::scaleObject (const std::string& handle, float scale) { - + if(handleToMesh.find(handle) != handleToMesh.end()) + { + btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform(); + removeObject(handle); + + Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ()); + Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()); + addObject(handle, handleToMesh[handle], quat, scale, vec); + } } bool PhysicsSystem::toggleCollisionMode() diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 6c4e426973..1dc38475d5 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -398,10 +398,16 @@ namespace Physic if (it != RigidBodyMap.end() ) { RigidBody* body = it->second; + btScaledBvhTriangleMeshShape* scaled = dynamic_cast (body->getCollisionShape()); + if(body != NULL) { delete body; } + if(scaled != NULL) + { + delete scaled; + } RigidBodyMap.erase(it); } } From 86d8a07fc71798927e0abfbd9f1deff1202da6e3 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 19 Jun 2012 13:28:06 -0400 Subject: [PATCH 23/51] Switching back to old scaling --- apps/openmw/mwworld/physicssystem.cpp | 5 ++++- libs/openengine/bullet/physic.cpp | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 530881ec92..94f39da7df 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -213,6 +213,8 @@ namespace MWWorld if(it->first == "player"){ coord = playerphysics->ps.origin; + //playerphysics->ps.speed = 480.0f; + //std::cout << "Position" << coord << "\n"; } @@ -300,6 +302,7 @@ namespace MWWorld void PhysicsSystem::scaleObject (const std::string& handle, float scale) { + /* if(handleToMesh.find(handle) != handleToMesh.end()) { btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform(); @@ -308,7 +311,7 @@ namespace MWWorld Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ()); Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()); addObject(handle, handleToMesh[handle], quat, scale, vec); - } + }*/ } bool PhysicsSystem::toggleCollisionMode() diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 1dc38475d5..6a3f22565d 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -324,24 +324,24 @@ namespace Physic RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) { - /*char uniqueID[8]; + char uniqueID[8]; sprintf( uniqueID, "%07.3f", scale ); std::string sid = uniqueID; - std::string outputstring = mesh + 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"); - //shape->Shape->setLocalScaling(); - btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast (shape->Shape), btVector3(scale,scale,scale)); + mShapeLoader->load(outputstring,"General"); + BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); + BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); + shape->Shape->setLocalScaling( btVector3(scale,scale,scale)); + //btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast (shape->Shape), btVector3(scale,scale,scale)); //create the motionState CMotionState* newMotionState = new CMotionState(this,name); //create the real body - btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,scaled); + btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; return body; @@ -398,16 +398,16 @@ namespace Physic if (it != RigidBodyMap.end() ) { RigidBody* body = it->second; - btScaledBvhTriangleMeshShape* scaled = dynamic_cast (body->getCollisionShape()); + //btScaledBvhTriangleMeshShape* scaled = dynamic_cast (body->getCollisionShape()); if(body != NULL) { delete body; } - if(scaled != NULL) + /*if(scaled != NULL) { delete scaled; - } + }*/ RigidBodyMap.erase(it); } } From 5c51674070a41a261b8d6b4b9b7b944960ce3326 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 20 Jun 2012 13:14:27 -0400 Subject: [PATCH 24/51] update --- apps/openmw/mwworld/physicssystem.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 94f39da7df..530881ec92 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -213,8 +213,6 @@ namespace MWWorld if(it->first == "player"){ coord = playerphysics->ps.origin; - //playerphysics->ps.speed = 480.0f; - //std::cout << "Position" << coord << "\n"; } @@ -302,7 +300,6 @@ namespace MWWorld void PhysicsSystem::scaleObject (const std::string& handle, float scale) { - /* if(handleToMesh.find(handle) != handleToMesh.end()) { btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform(); @@ -311,7 +308,7 @@ namespace MWWorld Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ()); Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()); addObject(handle, handleToMesh[handle], quat, scale, vec); - }*/ + } } bool PhysicsSystem::toggleCollisionMode() From 046e9686f9f845616b01f1cec5b5a8429651af71 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 2 Jul 2012 21:41:21 -0700 Subject: [PATCH 25/51] Cleanup RecordPtrT This moves the index resolution into a separate post method instead of always checking when access. As a result, it reduces the size of it down to the size of a pointer, as opposed to 2 pointers + 1 int. The appropriate methods are added to the various node types to make sure they're resolved. --- components/nif/controlled.hpp | 105 +-- components/nif/controller.hpp | 201 ++++-- components/nif/data.hpp | 1251 ++++++++++++++++----------------- components/nif/effect.hpp | 85 +-- components/nif/extra.hpp | 82 +-- components/nif/nif_file.cpp | 24 +- components/nif/nif_file.hpp | 142 ++-- components/nif/node.hpp | 296 ++++---- components/nif/property.hpp | 298 ++++---- components/nif/record.hpp | 27 +- components/nif/record_ptr.hpp | 136 ++-- 11 files changed, 1364 insertions(+), 1283 deletions(-) diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index d599501321..24281146f5 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -25,6 +25,7 @@ #define _NIF_CONTROLLED_H_ #include "extra.hpp" +#include "controller.hpp" namespace Nif { @@ -33,92 +34,104 @@ namespace Nif class Controlled : public Extra { public: - ControllerPtr controller; + ControllerPtr controller; - void read(NIFFile *nif) - { - Extra::read(nif); - controller.read(nif); - } + void read(NIFFile *nif) + { + Extra::read(nif); + controller.read(nif); + } + + void post(NIFFile *nif) + { + Extra::post(nif); + controller.post(nif); + } }; /// Has name, extra-data and controller class Named : public Controlled { public: - Misc::SString name; + Misc::SString name; - void read(NIFFile *nif) - { - name = nif->getString(); - Controlled::read(nif); - } + void read(NIFFile *nif) + { + name = nif->getString(); + Controlled::read(nif); + } }; typedef Named NiSequenceStreamHelper; class NiParticleGrowFade : public Controlled { public: - void read(NIFFile *nif) - { - Controlled::read(nif); + void read(NIFFile *nif) + { + Controlled::read(nif); - // Two floats. - nif->skip(8); - } + // Two floats. + nif->skip(8); + } }; class NiParticleColorModifier : public Controlled { public: - NiColorDataPtr data; + NiColorDataPtr data; - void read(NIFFile *nif) - { - Controlled::read(nif); - data.read(nif); - } + void read(NIFFile *nif) + { + Controlled::read(nif); + data.read(nif); + } + + void post(NIFFile *nif) + { + Controlled::post(nif); + data.post(nif); + } }; class NiGravity : public Controlled { public: - void read(NIFFile *nif) - { - Controlled::read(nif); + void read(NIFFile *nif) + { + Controlled::read(nif); - // two floats, one int, six floats - nif->skip(9*4); - } + // two floats, one int, six floats + nif->skip(9*4); + } }; // NiPinaColada class NiPlanarCollider : public Controlled { public: - void read(NIFFile *nif) - { - Controlled::read(nif); + void read(NIFFile *nif) + { + Controlled::read(nif); - // (I think) 4 floats + 4 vectors - nif->skip(4*16); - } + // (I think) 4 floats + 4 vectors + nif->skip(4*16); + } }; class NiParticleRotation : public Controlled { public: - void read(NIFFile *nif) - { - Controlled::read(nif); + void read(NIFFile *nif) + { + Controlled::read(nif); - /* - byte (0 or 1) - float (1) - float*3 - */ - nif->skip(17); - } + /* + byte (0 or 1) + float (1) + float*3 + */ + nif->skip(17); + } }; } // Namespace diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index d6fb222556..d00c1bc0ef 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -34,136 +34,187 @@ namespace Nif class Controller : public Record { public: - ControllerPtr next; - int flags; - float frequency, phase; - float timeStart, timeStop; - ControlledPtr target; + ControllerPtr next; + int flags; + float frequency, phase; + float timeStart, timeStop; + ControlledPtr target; - void read(NIFFile *nif) - { - next.read(nif); + void read(NIFFile *nif) + { + next.read(nif); - flags = nif->getShort(); + flags = nif->getShort(); - frequency = nif->getFloat(); - phase = nif->getFloat(); - timeStart = nif->getFloat(); - timeStop = nif->getFloat(); + frequency = nif->getFloat(); + phase = nif->getFloat(); + timeStart = nif->getFloat(); + timeStop = nif->getFloat(); - target.read(nif); - } + target.read(nif); + } + + void post(NIFFile *nif) + { + Record::post(nif); + next.post(nif); + target.post(nif); + } }; class NiBSPArrayController : public Controller { public: - void read(NIFFile *nif) - { - Controller::read(nif); + void read(NIFFile *nif) + { + Controller::read(nif); - // At the moment, just skip it all - nif->skip(111); - int s = nif->getShort(); - nif->skip(15 + s*40); - } + // At the moment, just skip it all + nif->skip(111); + int s = nif->getShort(); + nif->skip(15 + s*40); + } }; typedef NiBSPArrayController NiParticleSystemController; class NiMaterialColorController : public Controller { public: - NiPosDataPtr data; + NiPosDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); - data.read(nif); - } + void read(NIFFile *nif) + { + Controller::read(nif); + data.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; class NiPathController : public Controller { public: - NiPosDataPtr posData; - NiFloatDataPtr floatData; + NiPosDataPtr posData; + NiFloatDataPtr floatData; - void read(NIFFile *nif) - { - Controller::read(nif); + void read(NIFFile *nif) + { + Controller::read(nif); - /* - int = 1 - 2xfloat - short = 0 or 1 - */ - nif->skip(14); - posData.read(nif); - floatData.read(nif); - } + /* + int = 1 + 2xfloat + short = 0 or 1 + */ + nif->skip(14); + posData.read(nif); + floatData.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + + posData.post(nif); + floatData.post(nif); + } }; class NiUVController : public Controller { public: - NiUVDataPtr data; + NiUVDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); + void read(NIFFile *nif) + { + Controller::read(nif); - nif->getShort(); // always 0 - data.read(nif); - } + nif->getShort(); // always 0 + data.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; class NiKeyframeController : public Controller { public: - NiKeyframeDataPtr data; + NiKeyframeDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); - data.read(nif); - } + void read(NIFFile *nif) + { + Controller::read(nif); + data.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; class NiAlphaController : public Controller { public: - NiFloatDataPtr data; + NiFloatDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); - data.read(nif); - } + void read(NIFFile *nif) + { + Controller::read(nif); + data.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; class NiGeomMorpherController : public Controller { public: - NiMorphDataPtr data; + NiMorphDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); - data.read(nif); - nif->getByte(); // always 0 - } + void read(NIFFile *nif) + { + Controller::read(nif); + data.read(nif); + nif->getByte(); // always 0 + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; class NiVisController : public Controller { public: - NiVisDataPtr data; + NiVisDataPtr data; - void read(NIFFile *nif) - { - Controller::read(nif); - data.read(nif); - } + void read(NIFFile *nif) + { + Controller::read(nif); + data.read(nif); + } + + void post(NIFFile *nif) + { + Controller::post(nif); + data.post(nif); + } }; } // Namespace diff --git a/components/nif/data.hpp b/components/nif/data.hpp index df90797586..eaa11b5ee5 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -34,794 +34,777 @@ namespace Nif class NiSourceTexture : public Named { public: + // Is this an external (references a separate texture file) or + // internal (data is inside the nif itself) texture? + bool external; - // Is this an external (references a separate texture file) or - // internal (data is inside the nif itself) texture? - bool external; + Misc::SString filename; // In case of external textures + NiPixelDataPtr data; // In case of internal textures - Misc::SString filename; // In case of external textures - NiPixelDataPtr data; // In case of internal textures + /* Pixel layout + 0 - Palettised + 1 - High color 16 + 2 - True color 32 + 3 - Compressed + 4 - Bumpmap + 5 - Default */ + int pixel; - /* Pixel layout - 0 - Palettised - 1 - High color 16 - 2 - True color 32 - 3 - Compressed - 4 - Bumpmap - 5 - Default */ - int pixel; + /* Mipmap format + 0 - no + 1 - yes + 2 - default */ + int mipmap; - /* Mipmap format - 0 - no - 1 - yes - 2 - default */ - int mipmap; + /* Alpha + 0 - none + 1 - binary + 2 - smooth + 3 - default (use material alpha, or multiply material with texture if present) + */ + int alpha; - /* Alpha - 0 - none - 1 - binary - 2 - smooth - 3 - default (use material alpha, or multiply material with texture if present) - */ - int alpha; + void read(NIFFile *nif) + { + Named::read(nif); - void read(NIFFile *nif) - { - Named::read(nif); + external = !!nif->getByte(); + if(external) + filename = nif->getString(); + else + { + nif->getByte(); // always 1 + data.read(nif); + } - external = !!nif->getByte(); + pixel = nif->getInt(); + mipmap = nif->getInt(); + alpha = nif->getInt(); - if(external) filename = nif->getString(); - else - { nif->getByte(); // always 1 - data.read(nif); - } + } - pixel = nif->getInt(); - mipmap = nif->getInt(); - alpha = nif->getInt(); - - nif->getByte(); // always 1 - } + void post(NIFFile *nif) + { + Named::post(nif); + data.post(nif); + } }; // Common ancestor for several data classes class ShapeData : public Record { public: - Misc::FloatArray vertices, normals, colors, uvlist; - const Vector *center; - float radius; + Misc::FloatArray vertices, normals, colors, uvlist; + const Vector *center; + float radius; - void read(NIFFile *nif) - { - int verts = nif->getShort(); + void read(NIFFile *nif) + { + int verts = nif->getShort(); - if(nif->getInt()) - vertices = nif->getFloatLen(verts*3); + if(nif->getInt()) + vertices = nif->getFloatLen(verts*3); - if(nif->getInt()) - normals = nif->getFloatLen(verts*3); + if(nif->getInt()) + normals = nif->getFloatLen(verts*3); - center = nif->getVector(); - radius = nif->getFloat(); + center = nif->getVector(); + radius = nif->getFloat(); - if(nif->getInt()) - colors = nif->getFloatLen(verts*4); + if(nif->getInt()) + colors = nif->getFloatLen(verts*4); - int uvs = nif->getShort(); + int uvs = nif->getShort(); - // Only the first 6 bits are used as a count. I think the rest are - // flags of some sort. - uvs &= 0x3f; + // Only the first 6 bits are used as a count. I think the rest are + // flags of some sort. + uvs &= 0x3f; - if(nif->getInt()) - uvlist = nif->getFloatLen(uvs*verts*2); - } + if(nif->getInt()) + uvlist = nif->getFloatLen(uvs*verts*2); + } }; class NiTriShapeData : public ShapeData { public: - // Triangles, three vertex indices per triangle - Misc::SliceArray triangles; + // Triangles, three vertex indices per triangle + Misc::SliceArray triangles; - void read(NIFFile *nif) - { - ShapeData::read(nif); + void read(NIFFile *nif) + { + ShapeData::read(nif); - int tris = nif->getShort(); - if(tris) - { - // We have three times as many vertices as triangles, so this - // is always equal to tris*3. - int cnt = nif->getInt(); - triangles = nif->getArrayLen(cnt); - } + int tris = nif->getShort(); + if(tris) + { + // We have three times as many vertices as triangles, so this + // is always equal to tris*3. + int cnt = nif->getInt(); + triangles = nif->getArrayLen(cnt); + } - // Read the match list, which lists the vertices that are equal to - // vertices. We don't actually need need this for anything, so - // just skip it. - int verts = nif->getShort(); - if(verts) - { - for(int i=0;igetShort(); - nif->skip(num*sizeof(short)); - } - } - } + // Read the match list, which lists the vertices that are equal to + // vertices. We don't actually need need this for anything, so + // just skip it. + int verts = nif->getShort(); + if(verts) + { + for(int i=0;igetShort(); + nif->skip(num*sizeof(short)); + } + } + } }; class NiAutoNormalParticlesData : public ShapeData { public: - int activeCount; + int activeCount; - void read(NIFFile *nif) - { - ShapeData::read(nif); + void read(NIFFile *nif) + { + ShapeData::read(nif); - // Should always match the number of vertices - activeCount = nif->getShort(); + // Should always match the number of vertices + activeCount = nif->getShort(); - // Skip all the info, we don't support particles yet - nif->getFloat(); // Active radius ? - nif->getShort(); // Number of valid entries in the following arrays ? + // Skip all the info, we don't support particles yet + nif->getFloat(); // Active radius ? + nif->getShort(); // Number of valid entries in the following arrays ? - if(nif->getInt()) - // Particle sizes - nif->getFloatLen(activeCount); - } + if(nif->getInt()) + { + // Particle sizes + nif->getFloatLen(activeCount); + } + } }; class NiRotatingParticlesData : public NiAutoNormalParticlesData { public: - void read(NIFFile *nif) - { - NiAutoNormalParticlesData::read(nif); + void read(NIFFile *nif) + { + NiAutoNormalParticlesData::read(nif); - if(nif->getInt()) - // Rotation quaternions. I THINK activeCount is correct here, - // but verts (vertex number) might also be correct, if there is - // any case where the two don't match. - nif->getArrayLen(activeCount); - } + if(nif->getInt()) + { + // Rotation quaternions. I THINK activeCount is correct here, + // but verts (vertex number) might also be correct, if there is + // any case where the two don't match. + nif->getArrayLen(activeCount); + } + } }; class NiPosData : public Record { public: - void read(NIFFile *nif) - { - int count = nif->getInt(); - int type = nif->getInt(); - if(type != 1 && type != 2) - nif->fail("Cannot handle NiPosData type"); + void read(NIFFile *nif) + { + int count = nif->getInt(); + int type = nif->getInt(); + if(type != 1 && type != 2) + nif->fail("Cannot handle NiPosData type"); - // TODO: Could make structs of these. Seems to be identical to - // translation in NiKeyframeData. - for(int i=0; igetFloat(); - nif->getVector(); // This isn't really shared between type 1 - // and type 2, most likely - if(type == 2) - { - nif->getVector(); - nif->getVector(); - } - } - } + // TODO: Could make structs of these. Seems to be identical to + // translation in NiKeyframeData. + for(int i=0; igetFloat(); + nif->getVector(); // This isn't really shared between type 1 + // and type 2, most likely + if(type == 2) + { + nif->getVector(); + nif->getVector(); + } + } + } }; class NiUVData : public Record { public: - void read(NIFFile *nif) - { - // TODO: This is claimed to be a "float animation key", which is - // also used in FloatData and KeyframeData. We could probably - // reuse and refactor a lot of this if we actually use it at some - // point. - - for(int i=0; i<2; i++) - { - int count = nif->getInt(); - - if(count) - { - nif->getInt(); // always 2 - nif->getArrayLen(count); // Really one time float + one vector - } - } - // Always 0 - nif->getInt(); - nif->getInt(); - } + void read(NIFFile *nif) + { + // TODO: This is claimed to be a "float animation key", which is + // also used in FloatData and KeyframeData. We could probably + // reuse and refactor a lot of this if we actually use it at some + // point. + for(int i=0; i<2; i++) + { + int count = nif->getInt(); + if(count) + { + nif->getInt(); // always 2 + nif->getArrayLen(count); // Really one time float + one vector + } + } + // Always 0 + nif->getInt(); + nif->getInt(); + } }; class NiFloatData : public Record { public: - void read(NIFFile *nif) - { - int count = nif->getInt(); - nif->getInt(); // always 2 - nif->getArrayLen(count); // Really one time float + one vector - } + void read(NIFFile *nif) + { + int count = nif->getInt(); + nif->getInt(); // always 2 + nif->getArrayLen(count); // Really one time float + one vector + } }; class NiPixelData : public Record { public: - unsigned int rmask, gmask, bmask, amask; - int bpp, mips; + unsigned int rmask, gmask, bmask, amask; + int bpp, mips; - void read(NIFFile *nif) - { - nif->getInt(); // always 0 or 1 + void read(NIFFile *nif) + { + nif->getInt(); // always 0 or 1 - rmask = nif->getInt(); // usually 0xff - gmask = nif->getInt(); // usually 0xff00 - bmask = nif->getInt(); // usually 0xff0000 - amask = nif->getInt(); // usually 0xff000000 or zero + rmask = nif->getInt(); // usually 0xff + gmask = nif->getInt(); // usually 0xff00 + bmask = nif->getInt(); // usually 0xff0000 + amask = nif->getInt(); // usually 0xff000000 or zero - bpp = nif->getInt(); + bpp = nif->getInt(); - // Unknown - nif->skip(12); + // Unknown + nif->skip(12); - mips = nif->getInt(); + mips = nif->getInt(); - // Bytes per pixel, should be bpp * 8 - /*int bytes =*/ nif->getInt(); + // Bytes per pixel, should be bpp * 8 + /*int bytes =*/ nif->getInt(); - for(int i=0; igetInt(); - /*int y =*/ nif->getInt(); - /*int offset =*/ nif->getInt(); - } + for(int i=0; igetInt(); + /*int y =*/ nif->getInt(); + /*int offset =*/ nif->getInt(); + } - // Skip the data - unsigned int dataSize = nif->getInt(); - nif->skip(dataSize); - } + // Skip the data + unsigned int dataSize = nif->getInt(); + nif->skip(dataSize); + } }; class NiColorData : public Record { public: - struct ColorData - { - float time; - Vector4 rgba; - }; + struct ColorData + { + float time; + Vector4 rgba; + }; - void read(NIFFile *nif) - { - int count = nif->getInt(); - nif->getInt(); // always 1 + void read(NIFFile *nif) + { + int count = nif->getInt(); + nif->getInt(); // always 1 - // Skip the data - assert(sizeof(ColorData) == 4*5); - nif->skip(sizeof(ColorData) * count); - } + // Skip the data + assert(sizeof(ColorData) == 4*5); + nif->skip(sizeof(ColorData) * count); + } }; class NiVisData : public Record { public: - void read(NIFFile *nif) - { - int count = nif->getInt(); - /* - Each VisData consists of: - float time; - byte isSet; + void read(NIFFile *nif) + { + int count = nif->getInt(); + /* + Each VisData consists of: + float time; + byte isSet; - If you implement this, make sure you use a packed struct - (sizeof==5), or read each element individually. - */ - nif->skip(count*5); - } + If you implement this, make sure you use a packed struct + (sizeof==5), or read each element individually. + */ + nif->skip(count*5); + } }; class NiSkinInstance : public Record { public: - NiSkinDataPtr data; - NodePtr root; - NodeList bones; + NiSkinDataPtr data; + NodePtr root; + NodeList bones; - void read(NIFFile *nif) - { - data.read(nif); - root.read(nif); - bones.read(nif); + void read(NIFFile *nif) + { + data.read(nif); + root.read(nif); + bones.read(nif); + } - if(data.empty() || root.empty()) - nif->fail("NiSkinInstance missing root or data"); - } - - void post(NIFFile *nif); + void post(NIFFile *nif); }; class NiSkinData : public Record { public: - // This is to make sure the structs are packed, ie. that the - // compiler doesn't mess them up with extra alignment bytes. + // This is to make sure the structs are packed, ie. that the + // compiler doesn't mess them up with extra alignment bytes. #pragma pack(push) #pragma pack(1) - struct BoneTrafo - { - Matrix rotation; // Rotation offset from bone? - Vector trans; // Translation - float scale; // Probably scale (always 1) - }; - struct BoneTrafoCopy - { - Ogre::Quaternion rotation; - Ogre::Vector3 trans; - float scale; - }; + struct BoneTrafo + { + Matrix rotation; // Rotation offset from bone? + Vector trans; // Translation + float scale; // Probably scale (always 1) + }; + struct BoneTrafoCopy + { + Ogre::Quaternion rotation; + Ogre::Vector3 trans; + float scale; + }; - struct VertWeight - { - short vertex; - float weight; - }; + struct VertWeight + { + short vertex; + float weight; + }; #pragma pack(pop) - struct BoneInfo - { - const BoneTrafo *trafo; - const Vector4 *unknown; - Misc::SliceArray weights; - }; - struct BoneInfoCopy - { - std::string bonename; - unsigned short bonehandle; - BoneTrafoCopy trafo; - Vector4 unknown; - //std::vector weights; - }; - struct IndividualWeight - { - float weight; + struct BoneInfo + { + const BoneTrafo *trafo; + const Vector4 *unknown; + Misc::SliceArray weights; + }; + struct BoneInfoCopy + { + std::string bonename; + unsigned short bonehandle; + BoneTrafoCopy trafo; + Vector4 unknown; + //std::vector weights; + }; + struct IndividualWeight + { + float weight; unsigned int boneinfocopyindex; - }; + }; - const BoneTrafo *trafo; - std::vector bones; + const BoneTrafo *trafo; + std::vector bones; - void read(NIFFile *nif) - { - assert(sizeof(BoneTrafo) == 4*(9+3+1)); - assert(sizeof(VertWeight) == 6); + void read(NIFFile *nif) + { + assert(sizeof(BoneTrafo) == 4*(9+3+1)); + assert(sizeof(VertWeight) == 6); - trafo = nif->getPtr(); + trafo = nif->getPtr(); - int boneNum = nif->getInt(); - nif->getInt(); // -1 + int boneNum = nif->getInt(); + nif->getInt(); // -1 - bones.resize(boneNum); + bones.resize(boneNum); + for(int i=0;igetPtr(); + bi.unknown = nif->getVector4(); - bi.trafo = nif->getPtr(); - bi.unknown = nif->getVector4(); - - // Number of vertex weights - int count = nif->getShort(); - bi.weights = nif->getArrayLen(count); - } - } + // Number of vertex weights + int count = nif->getShort(); + bi.weights = nif->getArrayLen(count); + } + } }; class NiMorphData : public Record { - float startTime; - float stopTime; - std::vector initialVertices; - std::vector > relevantTimes; - std::vector > relevantData; - std::vector > additionalVertices; - + float startTime; + float stopTime; + std::vector initialVertices; + std::vector > relevantTimes; + std::vector > relevantData; + std::vector > additionalVertices; public: - float getStartTime(){ - return startTime; - } - float getStopTime(){ - return stopTime; - } - void setStartTime(float time){ - startTime = time; - } + float getStartTime() const + { return startTime; } + float getStopTime() const + { return stopTime; } - void setStopTime(float time){ - stopTime = time; - } - std::vector getInitialVertices(){ - return initialVertices; - } - std::vector > getRelevantData(){ - return relevantData; - } - std::vector > getRelevantTimes(){ - return relevantTimes; - } - std::vector > getAdditionalVertices(){ - return additionalVertices; - } - -void read(NIFFile *nif) - { - int morphCount = nif->getInt(); - int vertCount = nif->getInt(); - nif->getByte(); - int magic = nif->getInt(); - /*int type =*/ nif->getInt(); - for(int i = 0; i < vertCount; i++){ + void setStartTime(float time) + { startTime = time; } + void setStopTime(float time) + { stopTime = time; } - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - initialVertices.push_back(Ogre::Vector3(x, y, z)); - } - - for(int i=1; i& getInitialVertices() const + { return initialVertices; } + const std::vector >& getRelevantData() const + { return relevantData; } + const std::vector >& getRelevantTimes() const + { return relevantTimes; } + const std::vector >& getAdditionalVertices() const + { return additionalVertices; } + + void read(NIFFile *nif) { - magic = nif->getInt(); - /*type =*/ nif->getInt(); - std::vector current; - std::vector currentTime; - for(int i = 0; i < magic; i++){ - // Time, data, forward, backward tangents - float time = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - current.push_back(Ogre::Vector3(x,y,z)); - currentTime.push_back(time); - //nif->getFloatLen(4*magic); - } - if(magic){ - relevantData.push_back(current); - relevantTimes.push_back(currentTime); - } - std::vector verts; - for(int i = 0; i < vertCount; i++){ - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - verts.push_back(Ogre::Vector3(x, y, z)); - } - additionalVertices.push_back(verts); - } - } + int morphCount = nif->getInt(); + int vertCount = nif->getInt(); + nif->getByte(); + int magic = nif->getInt(); + /*int type =*/ nif->getInt(); + + for(int i = 0; i < vertCount; i++) + { + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + initialVertices.push_back(Ogre::Vector3(x, y, z)); + } + + for(int i=1; igetInt(); + /*type =*/ nif->getInt(); + std::vector current; + std::vector currentTime; + for(int i = 0; i < magic; i++) + { + // Time, data, forward, backward tangents + float time = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + current.push_back(Ogre::Vector3(x,y,z)); + currentTime.push_back(time); + //nif->getFloatLen(4*magic); + } + + if(magic) + { + relevantData.push_back(current); + relevantTimes.push_back(currentTime); + } + + std::vector verts; + for(int i = 0; i < vertCount; i++) + { + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + verts.push_back(Ogre::Vector3(x, y, z)); + } + additionalVertices.push_back(verts); + } + } }; class NiKeyframeData : public Record { - std::string bonename; - //Rotations - std::vector quats; - std::vector tbc; - std::vector rottime; - float startTime; - float stopTime; - int rtype; + std::string bonename; + //Rotations + std::vector quats; + std::vector tbc; + std::vector rottime; + float startTime; + float stopTime; + int rtype; - //Translations - std::vector translist1; - std::vector translist2; - std::vector translist3; - std::vector transtbc; - std::vector transtime; - int ttype; + //Translations + std::vector translist1; + std::vector translist2; + std::vector translist3; + std::vector transtbc; + std::vector transtime; + int ttype; - //Scalings + //Scalings + std::vector scalefactor; + std::vector scaletime; + std::vector forwards; + std::vector backwards; + std::vector tbcscale; + int stype; - std::vector scalefactor; - std::vector scaletime; - std::vector forwards; - std::vector backwards; - std::vector tbcscale; - int stype; - - - public: - void clone(NiKeyframeData c) - { - quats = c.getQuat(); - tbc = c.getrTbc(); - rottime = c.getrTime(); + void clone(const NiKeyframeData &c) + { + quats = c.getQuat(); + tbc = c.getrTbc(); + rottime = c.getrTime(); - //types - ttype = c.getTtype(); - rtype = c.getRtype(); - stype = c.getStype(); + //types + ttype = c.getTtype(); + rtype = c.getRtype(); + stype = c.getStype(); - translist1 = c.getTranslist1(); - translist2 = c.getTranslist2(); + translist1 = c.getTranslist1(); + translist2 = c.getTranslist2(); translist3 = c.getTranslist3(); - transtime = c.gettTime(); - - bonename = c.getBonename(); + transtime = c.gettTime(); + bonename = c.getBonename(); + } - } + void setBonename(std::string bone) + { bonename = bone; } + void setStartTime(float start) + { startTime = start; } + void setStopTime(float end) + { stopTime = end; } - void setBonename(std::string bone) - { - bonename = bone; - } - void setStartTime(float start) - { - startTime = start; - } - void setStopTime(float end) - { - stopTime = end; - } - void read(NIFFile *nif) - { - // Rotations first - int count = nif->getInt(); - //std::vector quat(count); - //std::vector rottime(count); - if(count) - { + void read(NIFFile *nif) + { + // Rotations first + int count = nif->getInt(); + //std::vector quat(count); + //std::vector rottime(count); + if(count) + { + //TYPE1 LINEAR_KEY + //TYPE2 QUADRATIC_KEY + //TYPE3 TBC_KEY + //TYPE4 XYZ_ROTATION_KEY + //TYPE5 UNKNOWN_KEY + rtype = nif->getInt(); + //std::cout << "Count: " << count << "Type: " << type << "\n"; - //TYPE1 LINEAR_KEY - //TYPE2 QUADRATIC_KEY - //TYPE3 TBC_KEY - //TYPE4 XYZ_ROTATION_KEY - //TYPE5 UNKNOWN_KEY - rtype = nif->getInt(); - //std::cout << "Count: " << count << "Type: " << type << "\n"; + if(rtype == 1) + { + //We need to actually read in these values instead of skipping them + //nif->skip(count*4*5); // time + quaternion + for (int i = 0; i < count; i++) + { + float time = nif->getFloat(); + float w = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); + quats.push_back(quat); + rottime.push_back(time); + //if(time == 0.0 || time > 355.5) + // std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n"; + } + } + else if(rtype == 3) + { + //Example - node 116 in base_anim.nif + for (int i = 0; i < count; i++) + { + float time = nif->getFloat(); + float w = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); - if(rtype == 1) - { - //We need to actually read in these values instead of skipping them - //nif->skip(count*4*5); // time + quaternion - for (int i = 0; i < count; i++) { - float time = nif->getFloat(); - float w = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); - quats.push_back(quat); - rottime.push_back(time); - //if(time == 0.0 || time > 355.5) - // std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n"; - } - } - else if(rtype == 3) - { //Example - node 116 in base_anim.nif - for (int i = 0; i < count; i++) { - float time = nif->getFloat(); - float w = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); + float tbcx = nif->getFloat(); + float tbcy = nif->getFloat(); + float tbcz = nif->getFloat(); - float tbcx = nif->getFloat(); - float tbcy = nif->getFloat(); - float tbcz = nif->getFloat(); - Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); - Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); - quats.push_back(quat); - rottime.push_back(time); - tbc.push_back(vec); - //if(time == 0.0 || time > 355.5) - // std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n"; - } + Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); + Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); + quats.push_back(quat); + rottime.push_back(time); + tbc.push_back(vec); + //if(time == 0.0 || time > 355.5) + // std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n"; + } + } + else if(rtype == 4) + { + for(int j=0;jgetFloat(); // time + for(int i=0; i<3; i++) + { + int cnt = nif->getInt(); + int type = nif->getInt(); + if(type == 1) + nif->skip(cnt*4*2); // time + unknown + else if(type == 2) + nif->skip(cnt*4*4); // time + unknown vector + else + nif->fail("Unknown sub-rotation type"); + } + } + } + else + nif->fail("Unknown rotation type in NiKeyframeData"); + } + //first = false; - //nif->skip(count*4*8); // rot1 + tension+bias+continuity - } - else if(rtype == 4) - { - for(int j=0;jgetFloat(); // time - for(int i=0; i<3; i++) - { - int cnt = nif->getInt(); - int type = nif->getInt(); - if(type == 1) - nif->skip(cnt*4*2); // time + unknown - else if(type == 2) - nif->skip(cnt*4*4); // time + unknown vector - else nif->fail("Unknown sub-rotation type"); - } - } - } - else nif->fail("Unknown rotation type in NiKeyframeData"); - } - //first = false; + // Then translation + count = nif->getInt(); + if(count) + { + ttype = nif->getInt(); - // Then translation - count = nif->getInt(); - - if(count) - { - ttype = nif->getInt(); + //std::cout << "TransCount:" << count << " Type: " << type << "\n"; + if(ttype == 1) + { + for(int i = 0; i < count; i++) + { + float time = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); - //std::cout << "TransCount:" << count << " Type: " << type << "\n"; - if(ttype == 1) { - for (int i = 0; i < count; i++) { - float time = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - Ogre::Vector3 trans = Ogre::Vector3(x, y, z); - translist1.push_back(trans); - transtime.push_back(time); - } - //nif->getFloatLen(count*4); // time + translation - } - else if(ttype == 2) - { //Example - node 116 in base_anim.nif - for (int i = 0; i < count; i++) { - float time = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - float x2 = nif->getFloat(); - float y2 = nif->getFloat(); - float z2 = nif->getFloat(); - float x3 = nif->getFloat(); - float y3 = nif->getFloat(); - float z3 = nif->getFloat(); - Ogre::Vector3 trans = Ogre::Vector3(x, y, z); - Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2); - Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3); - transtime.push_back(time); - translist1.push_back(trans); - translist2.push_back(trans2); - translist3.push_back(trans3); - } - - //nif->getFloatLen(count*10); // trans1 + forward + backward - } - else if(ttype == 3){ - for (int i = 0; i < count; i++) { - float time = nif->getFloat(); - float x = nif->getFloat(); - float y = nif->getFloat(); - float z = nif->getFloat(); - float t = nif->getFloat(); - float b = nif->getFloat(); - float c = nif->getFloat(); - Ogre::Vector3 trans = Ogre::Vector3(x, y, z); - Ogre::Vector3 tbc = Ogre::Vector3(t, b, c); - translist1.push_back(trans); - transtbc.push_back(tbc); - transtime.push_back(time); - } - //nif->getFloatLen(count*7); // trans1 + tension,bias,continuity - } - else nif->fail("Unknown translation type"); - } + Ogre::Vector3 trans = Ogre::Vector3(x, y, z); + translist1.push_back(trans); + transtime.push_back(time); + } + //nif->getFloatLen(count*4); // time + translation + } + else if(ttype == 2) + { + //Example - node 116 in base_anim.nif + for(int i = 0; i < count; i++) + { + float time = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + float x2 = nif->getFloat(); + float y2 = nif->getFloat(); + float z2 = nif->getFloat(); + float x3 = nif->getFloat(); + float y3 = nif->getFloat(); + float z3 = nif->getFloat(); - // Finally, scalings - count = nif->getInt(); - if(count) - { - stype = nif->getInt(); + Ogre::Vector3 trans = Ogre::Vector3(x, y, z); + Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2); + Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3); + transtime.push_back(time); + translist1.push_back(trans); + translist2.push_back(trans2); + translist3.push_back(trans3); + } - - for(int i = 0; i < count; i++){ - - - //int size = 0; - if(stype >= 1 && stype < 4) - { - float time = nif->getFloat(); - float scale = nif->getFloat(); - scaletime.push_back(time); - scalefactor.push_back(scale); - //size = 2; // time+scale - } - else nif->fail("Unknown scaling type"); - if(stype == 2){ - //size = 4; // 1 + forward + backward (floats) - float forward = nif->getFloat(); - float backward = nif->getFloat(); - forwards.push_back(forward); - backwards.push_back(backward); - } - else if(stype == 3){ - float tbcx = nif->getFloat(); - float tbcy = nif->getFloat(); - float tbcz = nif->getFloat(); - Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); - tbcscale.push_back(vec); + //nif->getFloatLen(count*10); // trans1 + forward + backward + } + else if(ttype == 3) + { + for(int i = 0; i < count; i++) + { + float time = nif->getFloat(); + float x = nif->getFloat(); + float y = nif->getFloat(); + float z = nif->getFloat(); + float t = nif->getFloat(); + float b = nif->getFloat(); + float c = nif->getFloat(); + Ogre::Vector3 trans = Ogre::Vector3(x, y, z); + Ogre::Vector3 tbc = Ogre::Vector3(t, b, c); + translist1.push_back(trans); + transtbc.push_back(tbc); + transtime.push_back(time); + } + //nif->getFloatLen(count*7); // trans1 + tension,bias,continuity + } + else nif->fail("Unknown translation type"); + } - //size = 5; // 1 + tbc - } - - } - } - else - stype = 0; - } - int getRtype(){ - return rtype; - } - int getStype(){ - return stype; - } - int getTtype(){ - return ttype; - } - float getStartTime(){ - return startTime; - } - float getStopTime(){ - return stopTime; - } - std::vector getQuat(){ - return quats; - } - std::vector getrTbc(){ - return tbc; - } - std::vector getrTime(){ - return rottime; - } + // Finally, scalings + count = nif->getInt(); + if(count) + { + stype = nif->getInt(); - std::vector getTranslist1(){ - return translist1; - } - std::vector getTranslist2(){ - return translist2; - } - std::vector getTranslist3(){ - return translist3; - } - std::vector gettTime(){ - return transtime; - } - std::vector getScalefactor(){ - return scalefactor; - } - std::vector getForwards(){ - return forwards; - } - std::vector getBackwards(){ - return backwards; - } - std::vector getScaleTbc(){ - return tbcscale; - } + for(int i = 0; i < count; i++) + { + //int size = 0; + if(stype >= 1 && stype < 4) + { + float time = nif->getFloat(); + float scale = nif->getFloat(); + scaletime.push_back(time); + scalefactor.push_back(scale); + //size = 2; // time+scale + } + else + nif->fail("Unknown scaling type"); - std::vector getsTime(){ - return scaletime; - } - std::string getBonename(){ return bonename; - } + if(stype == 2) + { + //size = 4; // 1 + forward + backward (floats) + float forward = nif->getFloat(); + float backward = nif->getFloat(); + forwards.push_back(forward); + backwards.push_back(backward); + } + else if(stype == 3) + { + //size = 5; // 1 + tbc + float tbcx = nif->getFloat(); + float tbcy = nif->getFloat(); + float tbcz = nif->getFloat(); + Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); + tbcscale.push_back(vec); + } + } + } + else + stype = 0; + } + int getRtype() const + { return rtype; } + int getStype() const + { return stype; } + int getTtype() const + { return ttype; } + float getStartTime() const + { return startTime; } + float getStopTime() const + { return stopTime; } + const std::vector& getQuat() const + { return quats; } + const std::vector& getrTbc() const + { return tbc; } + const std::vector& getrTime() const + { return rottime; } + const std::vector& getTranslist1() const + { return translist1; } + const std::vector& getTranslist2() const + { return translist2; } + const std::vector& getTranslist3() const + { return translist3; } + const std::vector& gettTime() const + { return transtime; } + const std::vector& getScalefactor() const + { return scalefactor; } + const std::vector& getForwards() const + { return forwards; } + const std::vector& getBackwards() const + { return backwards; } + const std::vector& getScaleTbc() const + { return tbcscale; } + + const std::vector& getsTime() const + { return scaletime; } + const std::string& getBonename() const + { return bonename; } }; } // Namespace diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index b0cc64228e..bac412c766 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -35,57 +35,62 @@ typedef Node Effect; // NiPointLight and NiSpotLight? struct NiLight : Effect { - struct SLight - { - float dimmer; - Vector ambient; - Vector diffuse; - Vector specular; - }; + struct SLight + { + float dimmer; + Vector ambient; + Vector diffuse; + Vector specular; + }; + const SLight *light; - const SLight *light; + void read(NIFFile *nif) + { + Effect::read(nif); - void read(NIFFile *nif) - { - Effect::read(nif); - - nif->getInt(); // 1 - nif->getInt(); // 1? - light = nif->getPtr(); - } + nif->getInt(); // 1 + nif->getInt(); // 1? + light = nif->getPtr(); + } }; struct NiTextureEffect : Effect { - NiSourceTexturePtr texture; + NiSourceTexturePtr texture; - void read(NIFFile *nif) - { - Effect::read(nif); + void read(NIFFile *nif) + { + Effect::read(nif); - int tmp = nif->getInt(); - if(tmp) nif->getInt(); // always 1? + int tmp = nif->getInt(); + if(tmp) nif->getInt(); // always 1? - /* - 3 x Vector4 = [1,0,0,0] - int = 2 - int = 0 or 3 - int = 2 - int = 2 - */ - nif->skip(16*4); + /* + 3 x Vector4 = [1,0,0,0] + int = 2 + int = 0 or 3 + int = 2 + int = 2 + */ + nif->skip(16*4); - texture.read(nif); + texture.read(nif); - /* - byte = 0 - vector4 = [1,0,0,0] - short = 0 - short = -75 - short = 0 - */ - nif->skip(23); - } + /* + byte = 0 + vector4 = [1,0,0,0] + short = 0 + short = -75 + short = 0 + */ + nif->skip(23); + } + + void post(NIFFile *nif) + { + Effect::post(nif); + texture.post(nif); + } }; } // Namespace diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index eec1aa7b48..ad788661af 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -38,70 +38,70 @@ namespace Nif class Extra : public Record { public: - ExtraPtr extra; + ExtraPtr extra; - void read(NIFFile *nif) { extra.read(nif); } + void read(NIFFile *nif) { extra.read(nif); } + void post(NIFFile *nif) { extra.post(nif); } }; class NiVertWeightsExtraData : public Extra { public: - void read(NIFFile *nif) - { - Extra::read(nif); + void read(NIFFile *nif) + { + Extra::read(nif); - // We should have s*4+2 == i, for some reason. Might simply be the - // size of the rest of the record, unhelpful as that may be. - /*int i =*/ nif->getInt(); - int s = nif->getShort(); // number of vertices + // We should have s*4+2 == i, for some reason. Might simply be the + // size of the rest of the record, unhelpful as that may be. + /*int i =*/ nif->getInt(); + int s = nif->getShort(); // number of vertices - nif->getFloatLen(s); // vertex weights I guess - } + nif->getFloatLen(s); // vertex weights I guess + } }; class NiTextKeyExtraData : public Extra { public: - struct TextKey - { - float time; - Misc::SString text; - }; + struct TextKey + { + float time; + Misc::SString text; + }; + std::vector list; - std::vector list; + void read(NIFFile *nif) + { + Extra::read(nif); - void read(NIFFile *nif) - { - Extra::read(nif); + nif->getInt(); // 0 - nif->getInt(); // 0 - - int keynum = nif->getInt(); - list.resize(keynum); - for(int i=0; igetFloat(); - list[i].text = nif->getString(); - } - } + int keynum = nif->getInt(); + list.resize(keynum); + for(int i=0; igetFloat(); + list[i].text = nif->getString(); + } + } }; class NiStringExtraData : public Extra { public: - /* Two known meanings: - "MRK" - marker, only visible in the editor, not rendered in-game - "NCO" - no collision - */ - Misc::SString string; + /* Two known meanings: + "MRK" - marker, only visible in the editor, not rendered in-game + "NCO" - no collision + */ + Misc::SString string; - void read(NIFFile *nif) - { - Extra::read(nif); + void read(NIFFile *nif) + { + Extra::read(nif); - nif->getInt(); // size of string + 4. Really useful... - string = nif->getString(); - } + nif->getInt(); // size of string + 4. Really useful... + string = nif->getString(); + } }; } // Namespace diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 80ea7a0b7f..48dd765106 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -190,17 +190,23 @@ void NIFFile::parse() void NiSkinInstance::post(NIFFile *nif) { - int bnum = bones.length(); - if(bnum != static_cast (data->bones.size())) - nif->fail("Mismatch in NiSkinData bone count"); + data.post(nif); + root.post(nif); + bones.post(nif); - root->makeRootBone(data->trafo); + if(data.empty() || root.empty()) + nif->fail("NiSkinInstance missing root or data"); - for(int i=0; ibones.size()) + nif->fail("Mismatch in NiSkinData bone count"); + + root->makeRootBone(data->trafo); + + for(int i=0; ifail("Oops: Missing bone! Don't know how to handle this."); - - bones[i].makeBone(i, data->bones[i]); + if(!bones.has(i)) + nif->fail("Oops: Missing bone! Don't know how to handle this."); + bones[i].makeBone(i, data->bones[i]); } } diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 951ae1f752..bb6f732599 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -43,113 +43,107 @@ namespace Nif class NIFFile { - enum NIFVersion - { - VER_MW = 0x04000002 // Morrowind NIFs + enum NIFVersion { + VER_MW = 0x04000002 // Morrowind NIFs }; - /// Nif file version - int ver; + /// Nif file version + int ver; - /// Input stream - StreamPtr inp; + /// Input stream + StreamPtr inp; - /// File name, used for error messages - std::string filename; + /// File name, used for error messages + std::string filename; - /// Record list - std::vector records; + /// Record list + std::vector records; - /// Parse the file - void parse(); + /// Parse the file + void parse(); - public: - /// Used for error handling - void fail(const std::string &msg) +public: + /// Used for error handling + void fail(const std::string &msg) { - std::string err = "NIFFile Error: " + msg; - err += "\nFile: " + filename; - throw std::runtime_error(err); + std::string err = "NIFFile Error: " + msg; + err += "\nFile: " + filename; + throw std::runtime_error(err); } - /// Open a NIF stream. The name is used for error messages. - NIFFile(StreamPtr nif, const std::string &name) - : filename(name) + /// Open a NIF stream. The name is used for error messages. + NIFFile(StreamPtr nif, const std::string &name) + : filename(name) { - /* Load the entire file into memory. This allows us to use - direct pointers to the data arrays in the NIF, instead of - individually allocating and copying each one. + /* Load the entire file into memory. This allows us to use + direct pointers to the data arrays in the NIF, instead of + individually allocating and copying each one. - The NIF data is only stored temporarily in memory, since once - the mesh data is loaded it is siphoned into OGRE and - deleted. For that reason, we might improve this further and - use a shared region/pool based allocation scheme in the - future, especially since only one NIFFile will ever be loaded - at any given time. - */ - inp = StreamPtr(new BufferStream(nif)); + The NIF data is only stored temporarily in memory, since once + the mesh data is loaded it is siphoned into OGRE and + deleted. For that reason, we might improve this further and + use a shared region/pool based allocation scheme in the + future, especially since only one NIFFile will ever be loaded + at any given time. + */ + inp = StreamPtr(new BufferStream(nif)); - parse(); + parse(); } - ~NIFFile() + ~NIFFile() { - for(std::size_t i=0; i= 0 && index < static_cast (records.size())); - Record *res = records[index]; - assert(res != NULL); - return res; - } + /// Get a given record + Record *getRecord(size_t index) + { + Record *res = records.at(index); + assert(res != NULL); + return res; + } - /// Number of records - int numRecords() { return records.size(); } - - /* ************************************************ + /// Number of records + int numRecords() { return records.size(); } + /************************************************* Parser functions + ****************************************************/ - ****************************************************/ + void skip(size_t size) { inp->getPtr(size); } - void skip(size_t size) { inp->getPtr(size); } + template const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); } + template X getType() { return *getPtr(); } + unsigned short getShort() { return getType(); } + int getInt() { return getType(); } + float getFloat() { return getType(); } + char getByte() { return getType(); } - template const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); } - template X getType() { return *getPtr(); } - unsigned short getShort() { return getType(); } - int getInt() { return getType(); } - float getFloat() { return getType(); } - char getByte() { return getType(); } - - template - Misc::SliceArray getArrayLen(int num) + template + Misc::SliceArray getArrayLen(int num) { return Misc::SliceArray((const X*)inp->getPtr(num*sizeof(X)),num); } - template - Misc::SliceArray getArray() + template + Misc::SliceArray getArray() { - int len = getInt(); - return getArrayLen(len); + int len = getInt(); + return getArrayLen(len); } - Misc::SString getString() { return getArray(); } + Misc::SString getString() { return getArray(); } - const Vector *getVector() { return getPtr(); } - const Matrix *getMatrix() { return getPtr(); } - const Transformation *getTrafo() { return getPtr(); } - const Vector4 *getVector4() { return getPtr(); } + const Vector *getVector() { return getPtr(); } + const Matrix *getMatrix() { return getPtr(); } + const Transformation *getTrafo() { return getPtr(); } + const Vector4 *getVector4() { return getPtr(); } - Misc::FloatArray getFloatLen(int num) + Misc::FloatArray getFloatLen(int num) { return getArrayLen(num); } - // For fixed-size strings where you already know the size - const char *getString(int size) + // For fixed-size strings where you already know the size + const char *getString(int size) { return (const char*)inp->getPtr(size); } }; diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 0800427466..fe9d10c7a6 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -26,6 +26,7 @@ #include "controlled.hpp" #include "data.hpp" +#include "property.hpp" namespace Nif { @@ -37,191 +38,220 @@ namespace Nif class Node : public Named { public: - // Node flags. Interpretation depends somewhat on the type of node. - int flags; - const Transformation *trafo; - PropertyList props; + // Node flags. Interpretation depends somewhat on the type of node. + int flags; + const Transformation *trafo; + PropertyList props; - // Bounding box info - bool hasBounds; - const Vector *boundPos; - const Matrix *boundRot; - const Vector *boundXYZ; // Box size + // Bounding box info + bool hasBounds; + const Vector *boundPos; + const Matrix *boundRot; + const Vector *boundXYZ; // Box size - void read(NIFFile *nif) - { - Named::read(nif); + void read(NIFFile *nif) + { + Named::read(nif); - flags = nif->getShort(); - trafo = nif->getTrafo(); - props.read(nif); + flags = nif->getShort(); + trafo = nif->getTrafo(); + props.read(nif); - hasBounds = !!nif->getInt(); - if(hasBounds) - { - nif->getInt(); // always 1 - boundPos = nif->getVector(); - boundRot = nif->getMatrix(); - boundXYZ = nif->getVector(); - } + hasBounds = !!nif->getInt(); + if(hasBounds) + { + nif->getInt(); // always 1 + boundPos = nif->getVector(); + boundRot = nif->getMatrix(); + boundXYZ = nif->getVector(); + } - boneTrafo = NULL; - boneIndex = -1; - } + boneTrafo = NULL; + boneIndex = -1; + } - // Bone transformation. If set, node is a part of a skeleton. - const NiSkinData::BoneTrafo *boneTrafo; + void post(NIFFile *nif) + { + Named::post(nif); + props.post(nif); + } - // Bone weight info, from NiSkinData - const NiSkinData::BoneInfo *boneInfo; + // Bone transformation. If set, node is a part of a skeleton. + const NiSkinData::BoneTrafo *boneTrafo; - // Bone index. If -1, this node is either not a bone, or if - // boneTrafo is set it is the root bone in the skeleton. - short boneIndex; + // Bone weight info, from NiSkinData + const NiSkinData::BoneInfo *boneInfo; - void makeRootBone(const NiSkinData::BoneTrafo *tr) - { - boneTrafo = tr; - boneIndex = -1; - } + // Bone index. If -1, this node is either not a bone, or if + // boneTrafo is set it is the root bone in the skeleton. + short boneIndex; - void makeBone(short ind, const NiSkinData::BoneInfo &bi) - { - boneInfo = &bi; - boneTrafo = bi.trafo; - boneIndex = ind; - } + void makeRootBone(const NiSkinData::BoneTrafo *tr) + { + boneTrafo = tr; + boneIndex = -1; + } + + void makeBone(short ind, const NiSkinData::BoneInfo &bi) + { + boneInfo = &bi; + boneTrafo = bi.trafo; + boneIndex = ind; + } }; struct NiTriShapeCopy { - std::string sname; - std::vector boneSequence; - Nif::NiSkinData::BoneTrafoCopy trafo; - //Ogre::Quaternion initialBoneRotation; - //Ogre::Vector3 initialBoneTranslation; - std::vector vertices; - std::vector normals; - std::vector boneinfo; - std::map > vertsToWeights; - Nif::NiMorphData morph; + std::string sname; + std::vector boneSequence; + Nif::NiSkinData::BoneTrafoCopy trafo; + //Ogre::Quaternion initialBoneRotation; + //Ogre::Vector3 initialBoneTranslation; + std::vector vertices; + std::vector normals; + std::vector boneinfo; + std::map > vertsToWeights; + Nif::NiMorphData morph; }; struct NiNode : Node { - NodeList children; - NodeList effects; + NodeList children; + NodeList effects; - /* Known NiNode flags: + /* Known NiNode flags: + 0x01 hidden + 0x02 use mesh for collision + 0x04 use bounding box for collision (?) + 0x08 unknown, but common + 0x20, 0x40, 0x80 unknown + */ - 0x01 hidden - 0x02 use mesh for collision - 0x04 use bounding box for collision (?) - 0x08 unknown, but common - 0x20, 0x40, 0x80 unknown - */ + void read(NIFFile *nif) + { + Node::read(nif); + children.read(nif); + effects.read(nif); + } - void read(NIFFile *nif) - { - Node::read(nif); - children.read(nif); - effects.read(nif); - } + void post(NIFFile *nif) + { + Node::post(nif); + children.post(nif); + effects.post(nif); + } }; struct NiTriShape : Node { - /* Possible flags: - 0x40 - mesh has no vertex normals ? + /* Possible flags: + 0x40 - mesh has no vertex normals ? - Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have - been observed so far. - */ + Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have + been observed so far. + */ - NiTriShapeDataPtr data; - NiSkinInstancePtr skin; + NiTriShapeDataPtr data; + NiSkinInstancePtr skin; - void read(NIFFile *nif) - { - Node::read(nif); - data.read(nif); - skin.read(nif); - } + void read(NIFFile *nif) + { + Node::read(nif); + data.read(nif); + skin.read(nif); + } - NiTriShapeCopy clone(){ - NiTriShapeCopy copy; - copy.sname = name.toString(); - float *ptr = (float*)data->vertices.ptr; - float *ptrNormals = (float*)data->normals.ptr; - int numVerts = data->vertices.length / 3; - for(int i = 0; i < numVerts; i++) - { - float *current = (float*) (ptr + i * 3); - copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2))); + void post(NIFFile *nif) + { + Node::post(nif); + data.post(nif); + skin.post(nif); + } - if(ptrNormals){ - float *currentNormals = (float*) (ptrNormals + i * 3); - copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2))); - } - } + NiTriShapeCopy clone() + { + NiTriShapeCopy copy; + copy.sname = name.toString(); + float *ptr = (float*)data->vertices.ptr; + float *ptrNormals = (float*)data->normals.ptr; + int numVerts = data->vertices.length / 3; + for(int i = 0; i < numVerts; i++) + { + float *current = (float*) (ptr + i * 3); + copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2))); + if(ptrNormals) + { + float *currentNormals = (float*) (ptrNormals + i * 3); + copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2))); + } + } - return copy; - } + return copy; + } }; struct NiCamera : Node { - struct Camera - { - // Camera frustrum - float left, right, top, bottom, nearDist, farDist; + struct Camera + { + // Camera frustrum + float left, right, top, bottom, nearDist, farDist; - // Viewport - float vleft, vright, vtop, vbottom; + // Viewport + float vleft, vright, vtop, vbottom; - // Level of detail modifier - float LOD; - }; + // Level of detail modifier + float LOD; + }; + const Camera *cam; - const Camera *cam; + void read(NIFFile *nif) + { + Node::read(nif); - void read(NIFFile *nif) - { - Node::read(nif); + nif->getPtr(); - nif->getPtr(); - - nif->getInt(); // -1 - nif->getInt(); // 0 - } + nif->getInt(); // -1 + nif->getInt(); // 0 + } }; struct NiAutoNormalParticles : Node { - NiAutoNormalParticlesDataPtr data; + NiAutoNormalParticlesDataPtr data; - void read(NIFFile *nif) - { - Node::read(nif); - data.read(nif); - nif->getInt(); // -1 - } + void read(NIFFile *nif) + { + Node::read(nif); + data.read(nif); + nif->getInt(); // -1 + } + + void post(NIFFile *nif) + { + Node::post(nif); + data.post(nif); + } }; struct NiRotatingParticles : Node { - NiRotatingParticlesDataPtr data; + NiRotatingParticlesDataPtr data; - void read(NIFFile *nif) - { - Node::read(nif); - data.read(nif); - nif->getInt(); // -1 - } + void read(NIFFile *nif) + { + Node::read(nif); + data.read(nif); + nif->getInt(); // -1 + } + + void post(NIFFile *nif) + { + Node::post(nif); + data.post(nif); + } }; - - } // Namespace #endif diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 1a16854af5..619e3db0e0 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -32,104 +32,116 @@ namespace Nif class Property : public Named { public: - // The meaning of these depends on the actual property type. - int flags; + // The meaning of these depends on the actual property type. + int flags; - void read(NIFFile *nif) - { - Named::read(nif); - flags = nif->getShort(); - } + void read(NIFFile *nif) + { + Named::read(nif); + flags = nif->getShort(); + } }; class NiTexturingProperty : public Property { public: - // A sub-texture - struct Texture - { - /* Clamp mode - 0 - clampS clampT - 1 - clampS wrapT - 2 - wrapS clampT - 3 - wrapS wrapT - */ + // A sub-texture + struct Texture + { + /* Clamp mode + 0 - clampS clampT + 1 - clampS wrapT + 2 - wrapS clampT + 3 - wrapS wrapT + */ - /* Filter: - 0 - nearest - 1 - bilinear - 2 - trilinear - 3, 4, 5 - who knows - */ - bool inUse; - NiSourceTexturePtr texture; + /* Filter: + 0 - nearest + 1 - bilinear + 2 - trilinear + 3, 4, 5 - who knows + */ + bool inUse; + NiSourceTexturePtr texture; - int clamp, set, filter; - short unknown2; + int clamp, set, filter; + short unknown2; + + void read(NIFFile *nif) + { + inUse = !!nif->getInt(); + if(!inUse) return; + + texture.read(nif); + clamp = nif->getInt(); + filter = nif->getInt(); + set = nif->getInt(); + + // I have no idea, but I think these are actually two + // PS2-specific shorts (ps2L and ps2K), followed by an unknown + // short. + nif->skip(6); + } + + void post(NIFFile *nif) + { + texture.post(nif); + } + }; + + /* Apply mode: + 0 - replace + 1 - decal + 2 - modulate + 3 - hilight // These two are for PS2 only? + 4 - hilight2 + */ + int apply; + + /* + * The textures in this list are as follows: + * + * 0 - Base texture + * 1 - Dark texture + * 2 - Detail texture + * 3 - Gloss texture (never used?) + * 4 - Glow texture + * 5 - Bump map texture + * 6 - Decal texture + */ + Texture textures[7]; void read(NIFFile *nif) { - inUse = !!nif->getInt(); - if(!inUse) return; + Property::read(nif); + apply = nif->getInt(); - texture.read(nif); - clamp = nif->getInt(); - filter = nif->getInt(); - set = nif->getInt(); + // Unknown, always 7. Probably the number of textures to read + // below + nif->getInt(); - // I have no idea, but I think these are actually two - // PS2-specific shorts (ps2L and ps2K), followed by an unknown - // short. - nif->skip(6); + textures[0].read(nif); // Base + textures[1].read(nif); // Dark + textures[2].read(nif); // Detail + textures[3].read(nif); // Gloss (never present) + textures[4].read(nif); // Glow + textures[5].read(nif); // Bump map + if(textures[5].inUse) + { + // Ignore these at the moment + /*float lumaScale =*/ nif->getFloat(); + /*float lumaOffset =*/ nif->getFloat(); + /*const Vector4 *lumaMatrix =*/ nif->getVector4(); + } + textures[6].read(nif); // Decal } - }; - /* Apply mode: - 0 - replace - 1 - decal - 2 - modulate - 3 - hilight // These two are for PS2 only? - 4 - hilight2 - */ - int apply; - - /* - * The textures in this list are as follows: - * - * 0 - Base texture - * 1 - Dark texture - * 2 - Detail texture - * 3 - Gloss texture (never used?) - * 4 - Glow texture - * 5 - Bump map texture - * 6 - Decal texture - */ - Texture textures[7]; - - void read(NIFFile *nif) - { - Property::read(nif); - apply = nif->getInt(); - - // Unknown, always 7. Probably the number of textures to read - // below - nif->getInt(); - - textures[0].read(nif); // Base - textures[1].read(nif); // Dark - textures[2].read(nif); // Detail - textures[3].read(nif); // Gloss (never present) - textures[4].read(nif); // Glow - textures[5].read(nif); // Bump map - if(textures[5].inUse) - { - // Ignore these at the moment - /*float lumaScale =*/ nif->getFloat(); - /*float lumaOffset =*/ nif->getFloat(); - /*const Vector4 *lumaMatrix =*/ nif->getVector4(); - } - textures[6].read(nif); // Decal - } + void post(NIFFile *nif) + { + Property::post(nif); + for(int i = 0;i < 7;i++) + textures[i].post(nif); + } }; // These contain no other data than the 'flags' field in Property @@ -140,88 +152,88 @@ typedef Property NiSpecularProperty; typedef Property NiWireframeProperty; // The rest are all struct-based -template +template struct StructPropT : Property { - const Struct* data; + const T* data; - void read(NIFFile *nif) - { - Property::read(nif); - data = nif->getPtr(); - } + void read(NIFFile *nif) + { + Property::read(nif); + data = nif->getPtr(); + } }; struct S_MaterialProperty { - // The vector components are R,G,B - Vector ambient, diffuse, specular, emissive; - float glossiness, alpha; + // The vector components are R,G,B + Vector ambient, diffuse, specular, emissive; + float glossiness, alpha; }; struct S_VertexColorProperty { - /* Vertex mode: - 0 - source ignore - 1 - source emmisive - 2 - source amb diff + /* Vertex mode: + 0 - source ignore + 1 - source emmisive + 2 - source amb diff - Lighting mode - 0 - lighting emmisive - 1 - lighting emmisive ambient/diffuse - */ - int vertmode, lightmode; + Lighting mode + 0 - lighting emmisive + 1 - lighting emmisive ambient/diffuse + */ + int vertmode, lightmode; }; struct S_AlphaProperty { - /* - In NiAlphaProperty, the flags have the following meaning: + /* + In NiAlphaProperty, the flags have the following meaning: - Bit 0 : alpha blending enable - Bits 1-4 : source blend mode - Bits 5-8 : destination blend mode - Bit 9 : alpha test enable - Bit 10-12 : alpha test mode - Bit 13 : no sorter flag ( disables triangle sorting ) + Bit 0 : alpha blending enable + Bits 1-4 : source blend mode + Bits 5-8 : destination blend mode + Bit 9 : alpha test enable + Bit 10-12 : alpha test mode + Bit 13 : no sorter flag ( disables triangle sorting ) - blend modes (glBlendFunc): - 0000 GL_ONE - 0001 GL_ZERO - 0010 GL_SRC_COLOR - 0011 GL_ONE_MINUS_SRC_COLOR - 0100 GL_DST_COLOR - 0101 GL_ONE_MINUS_DST_COLOR - 0110 GL_SRC_ALPHA - 0111 GL_ONE_MINUS_SRC_ALPHA - 1000 GL_DST_ALPHA - 1001 GL_ONE_MINUS_DST_ALPHA - 1010 GL_SRC_ALPHA_SATURATE + blend modes (glBlendFunc): + 0000 GL_ONE + 0001 GL_ZERO + 0010 GL_SRC_COLOR + 0011 GL_ONE_MINUS_SRC_COLOR + 0100 GL_DST_COLOR + 0101 GL_ONE_MINUS_DST_COLOR + 0110 GL_SRC_ALPHA + 0111 GL_ONE_MINUS_SRC_ALPHA + 1000 GL_DST_ALPHA + 1001 GL_ONE_MINUS_DST_ALPHA + 1010 GL_SRC_ALPHA_SATURATE - test modes (glAlphaFunc): - 000 GL_ALWAYS - 001 GL_LESS - 010 GL_EQUAL - 011 GL_LEQUAL - 100 GL_GREATER - 101 GL_NOTEQUAL - 110 GL_GEQUAL - 111 GL_NEVER + test modes (glAlphaFunc): + 000 GL_ALWAYS + 001 GL_LESS + 010 GL_EQUAL + 011 GL_LEQUAL + 100 GL_GREATER + 101 GL_NOTEQUAL + 110 GL_GEQUAL + 111 GL_NEVER - Taken from: - http://niftools.sourceforge.net/doc/nif/NiAlphaProperty.html + Taken from: + http://niftools.sourceforge.net/doc/nif/NiAlphaProperty.html - Right now we only use standard alpha blending (see the Ogre code - that sets it up) and it appears that this is the only blending - used in the original game. Bloodmoon (along with several mods) do - however use other settings, such as discarding pixel values with - alpha < 1.0. This is faster because we don't have to mess with the - depth stuff like we did for blending. And OGRE has settings for - this too. - */ + Right now we only use standard alpha blending (see the Ogre code + that sets it up) and it appears that this is the only blending + used in the original game. Bloodmoon (along with several mods) do + however use other settings, such as discarding pixel values with + alpha < 1.0. This is faster because we don't have to mess with the + depth stuff like we did for blending. And OGRE has settings for + this too. + */ - // Tested against when certain flags are set (see above.) - unsigned char threshold; + // Tested against when certain flags are set (see above.) + unsigned char threshold; }; typedef StructPropT NiAlphaProperty; diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 40f91f84f8..06fdce55e7 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -88,26 +88,25 @@ enum RecordType /// Base class for all records struct Record { - // Record type and type name - int recType; - Misc::SString recName; + // Record type and type name + int recType; + Misc::SString recName; - Record() : recType(RC_MISSING) {} + Record() : recType(RC_MISSING) {} - /// Parses the record from file - virtual void read(NIFFile *nif) = 0; + /// Parses the record from file + virtual void read(NIFFile *nif) = 0; - /// Does post-processing, after the entire tree is loaded - virtual void post(NIFFile *nif) {} + /// Does post-processing, after the entire tree is loaded + virtual void post(NIFFile *nif) {} virtual ~Record() {} - /* - Use these later if you want custom allocation of all NIF objects - - static void* operator new(size_t size); - static void operator delete(void *p); - */ + /* + Use these later if you want custom allocation of all NIF objects + static void* operator new(size_t size); + static void operator delete(void *p); + */ }; } // Namespace diff --git a/components/nif/record_ptr.hpp b/components/nif/record_ptr.hpp index c5618941ef..ac91e25e3b 100644 --- a/components/nif/record_ptr.hpp +++ b/components/nif/record_ptr.hpp @@ -37,61 +37,51 @@ namespace Nif template class RecordPtrT { - int index; - X* ptr; - NIFFile *nif; + union { + intptr_t index; + X* ptr; + }; - public: +public: + RecordPtrT() : index(-2) {} - RecordPtrT() : index(-2), ptr(NULL) {} + /// Read the index from the nif + void read(NIFFile *nif) + { + // Can only read the index once + assert(index == -2); - /// Read the index from the nif - void read(NIFFile *_nif) - { - // Can only read the index once - assert(index == -2); + // Store the index for later + index = nif->getInt(); + } - // Store the NIFFile pointer for later - nif = _nif; + /// Resolve index to pointer + void post(NIFFile *nif) + { + if(index < 0) + ptr = NULL; + else + { + Record *r = nif->getRecord(index); + // And cast it + ptr = dynamic_cast(r); + assert(ptr != NULL); + } + } - // And the index, of course - index = nif->getInt(); - } - - /** Set the pointer explicitly. May be used when you are pointing to - records in another file, eg. when you have a .nif / .kf pair. - */ - void set(X *p) - { - ptr = p; - index = -1; - } - - /// Look up the actual object from the index - X* getPtr() - { - // Have we found the pointer already? - if(ptr == NULL) - { - // Get the record - assert(index >= 0); - Record *r = nif->getRecord(index); - - // And cast it - ptr = dynamic_cast(r); + /// Look up the actual object from the index + X* getPtr() + { assert(ptr != NULL); - } - return ptr; - } + return ptr; + } + X& get() { return *getPtr(); } - /// Syntactic sugar - X* operator->() { return getPtr(); } - X& get() { return *getPtr(); } + /// Syntactic sugar + X* operator->() { return getPtr(); } - /// Pointers are allowed to be empty - bool empty() { return index == -1 && ptr == NULL; } - - int getIndex() { return index; } + /// Pointers are allowed to be empty + bool empty() { return ptr == NULL; } }; /** A list of references to other records. These are read as a list, @@ -101,40 +91,38 @@ class RecordPtrT template class RecordListT { - typedef RecordPtrT Ptr; - std::vector list; + typedef RecordPtrT Ptr; + std::vector list; - public: - - void read(NIFFile *nif) - { - int len = nif->getInt(); - list.resize(len); - - assert(len >= 0 && len < 1000); - for(int i=0;i= 0 && index < static_cast (list.size())); - return list[index].get(); + int len = nif->getInt(); + list.resize(len); + + for(size_t i=0;i < list.size();i++) + list[i].read(nif); } - bool has(int index) - { - assert(index >= 0 && index < static_cast (list.size())); - return !list[index].empty(); - } - - int getIndex(int index) + void post(NIFFile *nif) { - if(has(index)) return list[index].getIndex(); - else return -1; + for(size_t i=0;i < list.size();i++) + list[i].post(nif); } - int length() { return list.size(); } + X& operator[](size_t index) + { + return list.at(index).get(); + } + + bool has(size_t index) + { + assert(index >= 0 && index < static_cast (list.size())); + return !list.at(index).empty(); + } + + int length() + { return list.size(); } }; From 291599c6098c446d4cf00b9f18342d040f5b59ab Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 2 Jul 2012 22:49:44 -0700 Subject: [PATCH 26/51] Store the parents of NIF's nodes --- components/nif/node.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/nif/node.hpp b/components/nif/node.hpp index fe9d10c7a6..e4cc9291ed 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -31,6 +31,8 @@ namespace Nif { +class NiNode; + /** A Node is an object that's part of the main NIF tree. It has parent node (unless it's the root), and transformation (location and rotation) relative to it's parent. @@ -66,6 +68,8 @@ public: boundXYZ = nif->getVector(); } + parent = NULL; + boneTrafo = NULL; boneIndex = -1; } @@ -76,6 +80,10 @@ public: props.post(nif); } + // Parent node, or NULL for the root node. As far as I'm aware, only + // NiNodes (or types derived from NiNodes) can be parents. + NiNode *parent; + // Bone transformation. If set, node is a part of a skeleton. const NiSkinData::BoneTrafo *boneTrafo; @@ -139,6 +147,9 @@ struct NiNode : Node Node::post(nif); children.post(nif); effects.post(nif); + + for(size_t i = 0;i < children.length();i++) + children[i].parent = this; } }; From d8d00123ea34662282e461dd3253dbd4b90fe908 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 3 Jul 2012 18:37:04 -0700 Subject: [PATCH 27/51] Watch for empty children node refs when setting parents --- components/nif/nif_file.cpp | 2 +- components/nif/node.hpp | 6 +++++- components/nif/record_ptr.hpp | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 48dd765106..42aa43f8b1 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -203,7 +203,7 @@ void NiSkinInstance::post(NIFFile *nif) root->makeRootBone(data->trafo); - for(int i=0; ifail("Oops: Missing bone! Don't know how to handle this."); diff --git a/components/nif/node.hpp b/components/nif/node.hpp index e4cc9291ed..5a2847b6c2 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -149,7 +149,11 @@ struct NiNode : Node effects.post(nif); for(size_t i = 0;i < children.length();i++) - children[i].parent = this; + { + // Why would a unique list of children contain empty refs? + if(children.has(i)) + children[i].parent = this; + } } }; diff --git a/components/nif/record_ptr.hpp b/components/nif/record_ptr.hpp index ac91e25e3b..755094147e 100644 --- a/components/nif/record_ptr.hpp +++ b/components/nif/record_ptr.hpp @@ -53,6 +53,7 @@ public: // Store the index for later index = nif->getInt(); + assert(index >= -1); } /// Resolve index to pointer @@ -117,11 +118,10 @@ public: bool has(size_t index) { - assert(index >= 0 && index < static_cast (list.size())); return !list.at(index).empty(); } - int length() + size_t length() { return list.size(); } }; From 1a5203749f6800e6674583ecdfb82f890fec80ff Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 5 Jul 2012 17:13:23 +0200 Subject: [PATCH 28/51] fix "error in framelistener" when trying to pick up lights that can't be picked up --- apps/openmw/mwgui/inventorywindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index dc57282830..23a96b1d35 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -310,6 +310,9 @@ namespace MWGui && (type != typeid(ESM::Potion).name())) return; + if (MWWorld::Class::get(object).getName(object) == "") // objects without name presented to user can never be picked up + return; + // sound std::string sound = MWWorld::Class::get(object).getUpSoundId(object); MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1); From 113457d9348ded20223560994bbf2ec55b152b9e Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Sat, 7 Jul 2012 01:14:18 +0200 Subject: [PATCH 29/51] Fixed some windows issues and got rid of a few tiny warnings while at it. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 2 +- apps/openmw/mwgui/hud.cpp | 2 +- apps/openmw/mwgui/referenceinterface.cpp | 4 ++++ apps/openmw/mwgui/referenceinterface.hpp | 1 + apps/openmw/mwgui/tooltips.cpp | 2 +- apps/openmw/mwsound/soundmanager.cpp | 2 +- apps/openmw/mwworld/cells.cpp | 2 +- apps/openmw/mwworld/player.hpp | 3 +++ apps/openmw/mwworld/worldimp.hpp | 2 +- 9 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 98562c053b..41ffd1e930 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -706,7 +706,7 @@ namespace MWDialogue } return false; } - catch (const Compiler::SourceException& error) + catch (const Compiler::SourceException& /* error */) { // error has already been reported via error handler } diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index d20a110093..78eefa338e 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -286,7 +286,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) { object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); } - catch (std::exception& e) + catch (std::exception& /* e */) { return; } diff --git a/apps/openmw/mwgui/referenceinterface.cpp b/apps/openmw/mwgui/referenceinterface.cpp index f891b3338f..b1f7affb6f 100644 --- a/apps/openmw/mwgui/referenceinterface.cpp +++ b/apps/openmw/mwgui/referenceinterface.cpp @@ -12,6 +12,10 @@ namespace MWGui { } + ReferenceInterface::~ReferenceInterface() + { + } + void ReferenceInterface::checkReferenceAvailable() { if (mPtr.isEmpty()) diff --git a/apps/openmw/mwgui/referenceinterface.hpp b/apps/openmw/mwgui/referenceinterface.hpp index aba9071f3d..39574d0f7a 100644 --- a/apps/openmw/mwgui/referenceinterface.hpp +++ b/apps/openmw/mwgui/referenceinterface.hpp @@ -13,6 +13,7 @@ namespace MWGui { public: ReferenceInterface(); + virtual ~ReferenceInterface(); void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 7920d88a3d..679c7a59eb 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -81,7 +81,7 @@ void ToolTips::onFrame(float frameDuration) { mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); } - catch (std::exception& e) + catch (std::exception /* & e */) { return; } diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 29563ecc13..c6332d9f32 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -90,7 +90,7 @@ namespace MWSound { if(devname.empty()) throw; - std::cout <<"Failed to open device \""<init(); Settings::Manager::setString("device", "Sound", ""); } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 74a91f25fd..cd7ebf79a4 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -91,7 +91,7 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellS MWWorld::Cells::Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader) : mStore (store), mReader (reader), - mIdCache (20, std::pair ("", 0)), /// \todo make cache size configurable + mIdCache (20, std::pair ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable mIdCacheIndex (0) {} diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index b1692bd81a..6f6ee93bc6 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -9,6 +9,9 @@ #include "../mwmechanics/drawstate.hpp" +#undef DrawState // How did this get defined again? + // Maybe it's defined by default in every file for windows? + namespace MWBase { class World; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d64b3a373b..62a24000e3 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -188,7 +188,7 @@ namespace MWWorld virtual bool toggleSky(); ///< \return Resulting mode - virtual void changeWeather (const std::string& region, const unsigned int id); + virtual void changeWeather (const std::string& region, unsigned int id); virtual int getCurrentWeather() const; From e6716c25c382514eb06e6aeaaf4b2562e34fde7e Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Jul 2012 15:41:19 +0200 Subject: [PATCH 30/51] little correction. --- apps/openmw/mwworld/worldimp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index b623cd5275..155bc8d815 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -604,7 +604,7 @@ namespace MWWorld ptr.getCellRef().scale = scale; scale = scale/ptr.getRefData().getBaseNode()->getScale().x; ptr.getRefData().getBaseNode()->setScale(scale,scale,scale); - mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); + mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); } void World::rotateObject (Ptr& ptr,float x,float y,float z,bool WorldAxis) @@ -636,7 +636,7 @@ namespace MWWorld ptr.getRefData().getPosition().rot[0] = ry.valueRadians(); ptr.getRefData().getPosition().rot[0] = rz.valueRadians(); - mPhysics->rotateObject(Class::get(ptr).getId(ptr),ptr.getRefData().getBaseNode()->getOrientation()); + mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); //ptr.getRefData().getBaseNode()->rotate(ptr.getRefData().getBaseNode()->get //mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); } From 0a67f60a6e334a942cda7f5391b41fcf948e3d06 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Jul 2012 18:47:59 +0200 Subject: [PATCH 31/51] Clean-up --- apps/openmw/mwbase/world.hpp | 6 +- apps/openmw/mwscript/extensions.cpp | 3 + apps/openmw/mwscript/statsextensions.cpp | 57 ------------ .../mwscript/transformationextensions.cpp | 89 +++++++++++++++++++ .../mwscript/transformationextensions.hpp | 25 ++++++ apps/openmw/mwworld/worldimp.cpp | 41 +-------- apps/openmw/mwworld/worldimp.hpp | 6 +- 7 files changed, 124 insertions(+), 103 deletions(-) create mode 100644 apps/openmw/mwscript/transformationextensions.cpp create mode 100644 apps/openmw/mwscript/transformationextensions.hpp diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 0dcf440f08..51d0a4f8ef 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -178,11 +178,9 @@ namespace MWBase virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; - virtual void scaleObject (MWWorld::Ptr& ptr, float scale) = 0; + virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; - virtual void rotateObject (MWWorld::Ptr& ptr,float x,float y,float z,bool WorldAxis) = 0; - - virtual void setObjectRotation (MWWorld::Ptr& ptr,float x,float y,float z) = 0; + virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0; virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const = 0; diff --git a/apps/openmw/mwscript/extensions.cpp b/apps/openmw/mwscript/extensions.cpp index 1974941461..b7425aca0b 100644 --- a/apps/openmw/mwscript/extensions.cpp +++ b/apps/openmw/mwscript/extensions.cpp @@ -15,6 +15,7 @@ #include "controlextensions.hpp" #include "dialogueextensions.hpp" #include "animationextensions.hpp" +#include "transformationextensions.hpp" namespace MWScript { @@ -31,6 +32,7 @@ namespace MWScript Control::registerExtensions (extensions); Dialogue::registerExtensions (extensions); Animation::registerExtensions (extensions); + Transformation::registerExtensions (extensions); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -47,5 +49,6 @@ namespace MWScript Control::installOpcodes (interpreter); Dialogue::installOpcodes (interpreter); Animation::installOpcodes (interpreter); + Transformation::installOpcodes (interpreter); } } diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 17cd184d75..4e41ae81d8 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -505,50 +505,6 @@ namespace MWScript } }; - template - class OpSetScale : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWWorld::Ptr ptr = R()(runtime); - - Interpreter::Type_Float scale = runtime[0].mInteger; - runtime.pop(); - - MWBase::Environment::get().getWorld()->scaleObject(ptr,scale); - } - }; - - template - class OpSetAngle : public Interpreter::Opcode0 - { - public: - - virtual void execute (Interpreter::Runtime& runtime) - { - MWWorld::Ptr ptr = R()(runtime); - - std::string axis = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float angle = runtime[0].mInteger; - runtime.pop(); - - if(axis == "X") - { - MWBase::Environment::get().getWorld()->setObjectRotation(ptr,angle,0,0); - } - if(axis == "Y") - { - MWBase::Environment::get().getWorld()->setObjectRotation(ptr,0,angle,0); - } - if(axis == "Z") - { - MWBase::Environment::get().getWorld()->setObjectRotation(ptr,0,0,angle); - } - } - }; const int numberOfAttributes = 8; @@ -596,11 +552,6 @@ namespace MWScript const int opcodeModDisposition = 0x200014d; const int opcodeModDispositionExplicit = 0x200014e; - const int opcodeSetScale = 0x2000164; - const int opcodeSetScaleExplicit = 0x2000165; - const int opcodeSetAngle = 0x2000166; - const int opcodeSetAngleExplicit = 0x2000167; - void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -683,9 +634,6 @@ namespace MWScript extensions.registerInstruction("moddisposition","l",opcodeModDisposition, opcodeModDispositionExplicit); extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); - - extensions.registerInstruction("setscale","l",opcodeSetScale,opcodeSetScaleExplicit); - extensions.registerInstruction("setangle","Sl",opcodeSetAngle,opcodeSetAngleExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -757,11 +705,6 @@ namespace MWScript interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank); interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); - - interpreter.installSegment5(opcodeSetScale,new OpSetScale); - interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale); - interpreter.installSegment5(opcodeSetAngle,new OpSetAngle); - interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle); } } } diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp new file mode 100644 index 0000000000..14181a06e2 --- /dev/null +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -0,0 +1,89 @@ + +#include "statsextensions.hpp" + +#include + +#include + +#include + +#include +#include +#include + +#include "../mwbase/environment.hpp" + +#include "../mwworld/class.hpp" + +#include "interpretercontext.hpp" +#include "ref.hpp" + +namespace MWScript +{ + namespace Transformation + { + template + class OpSetScale : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Float scale = runtime[0].mInteger; + runtime.pop(); + + MWBase::Environment::get().getWorld()->scaleObject(ptr,scale); + } + }; + + template + class OpSetAngle : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float angle = runtime[0].mInteger; + runtime.pop(); + + if(axis == "X") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,0,0); + } + if(axis == "Y") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,0,angle,0); + } + if(axis == "Z") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,0,0,angle); + } + } + }; + + const int opcodeSetScale = 0x2000164; + const int opcodeSetScaleExplicit = 0x2000165; + const int opcodeSetAngle = 0x2000166; + const int opcodeSetAngleExplicit = 0x2000167; + + void registerExtensions (Compiler::Extensions& extensions) + { + extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit); + extensions.registerInstruction("setangle","Sl",opcodeSetAngle,opcodeSetAngleExplicit); + } + + void installOpcodes (Interpreter::Interpreter& interpreter) + { + interpreter.installSegment5(opcodeSetScale,new OpSetScale); + interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale); + interpreter.installSegment5(opcodeSetAngle,new OpSetAngle); + interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle); + } + } +} diff --git a/apps/openmw/mwscript/transformationextensions.hpp b/apps/openmw/mwscript/transformationextensions.hpp new file mode 100644 index 0000000000..6ee1db1b8e --- /dev/null +++ b/apps/openmw/mwscript/transformationextensions.hpp @@ -0,0 +1,25 @@ +#ifndef GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H +#define GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H + +namespace Compiler +{ + class Extensions; +} + +namespace Interpreter +{ + class Interpreter; +} + +namespace MWScript +{ + /// \brief stats-related script functionality (creatures and NPCs) + namespace Transformation + { + void registerExtensions (Compiler::Extensions& extensions); + + void installOpcodes (Interpreter::Interpreter& interpreter); + } +} + +#endif \ No newline at end of file diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 155bc8d815..c6423563d1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -597,7 +597,7 @@ namespace MWWorld mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); } - void World::scaleObject (Ptr& ptr, float scale) + void World::scaleObject (const Ptr& ptr, float scale) { MWWorld::Class::get(ptr).adjustScale(ptr,scale); @@ -607,41 +607,7 @@ namespace MWWorld mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); } - void World::rotateObject (Ptr& ptr,float x,float y,float z,bool WorldAxis) - { - MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); - - if(WorldAxis) - { - ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(x)); - ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(y)); - ptr.getRefData().getBaseNode()->rotate(Ogre::Vector3::UNIT_X,Ogre::Degree(z)); - } - else - { - Ogre::Matrix3 axis = ptr.getRefData().getBaseNode()->getLocalAxes(); - Ogre::Vector3 xAxis = axis.GetColumn(0); - Ogre::Vector3 yAxis = axis.GetColumn(1); - Ogre::Vector3 zAxis = axis.GetColumn(2); - ptr.getRefData().getBaseNode()->rotate(xAxis,Ogre::Degree(x)); - ptr.getRefData().getBaseNode()->rotate(yAxis,Ogre::Degree(y)); - ptr.getRefData().getBaseNode()->rotate(zAxis,Ogre::Degree(z)); - } - Ogre::Matrix3 rot; - ptr.getRefData().getBaseNode()->getOrientation().ToRotationMatrix(rot); - Ogre::Radian rx,ry,rz; - rot.ToEulerAnglesXYZ(rx,ry,rz); - - ptr.getRefData().getPosition().rot[0] = rx.valueRadians(); - ptr.getRefData().getPosition().rot[0] = ry.valueRadians(); - ptr.getRefData().getPosition().rot[0] = rz.valueRadians(); - - mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); - //ptr.getRefData().getBaseNode()->rotate(ptr.getRefData().getBaseNode()->get - //mPhysics->scaleObject( Class::get(ptr).getId(ptr), scale ); - } - - void World::setObjectRotation (Ptr& ptr,float x,float y,float z) + void World::rotateObject (const Ptr& ptr,float x,float y,float z) { MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); @@ -653,8 +619,7 @@ namespace MWWorld Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); - mPhysics->rotateObject(Class::get(ptr).getId(ptr),ptr.getRefData().getBaseNode()->getOrientation()); - std::cout << Class::get(ptr).getId(ptr); + mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 1f3073d446..8b39a78f1f 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -219,11 +219,9 @@ namespace MWWorld virtual void moveObject (const Ptr& ptr, float x, float y, float z); - virtual void scaleObject (Ptr& ptr, float scale); + virtual void scaleObject (const Ptr& ptr, float scale); - virtual void rotateObject (Ptr& ptr,float x,float y,float z,bool WorldAxis); - - virtual void setObjectRotation (Ptr& ptr,float x,float y,float z); + virtual void rotateObject (const Ptr& ptr,float x,float y,float z); virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; From 557e114992458b1d7c2768baaf342a64dc01542e Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Jul 2012 19:28:44 +0200 Subject: [PATCH 32/51] clean-up + getScale/Angle script instructions --- .../mwscript/transformationextensions.cpp | 59 +++++++++++++++++-- apps/openmw/mwworld/worldimp.cpp | 4 +- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 14181a06e2..41eba4a994 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -1,6 +1,3 @@ - -#include "statsextensions.hpp" - #include #include @@ -17,6 +14,7 @@ #include "interpretercontext.hpp" #include "ref.hpp" +#include "OgreSceneNode.h" namespace MWScript { @@ -31,13 +29,25 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float scale = runtime[0].mInteger; + Interpreter::Type_Float scale = runtime[0].mFloat; runtime.pop(); MWBase::Environment::get().getWorld()->scaleObject(ptr,scale); } }; + template + class OpGetScale : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(ptr.getCellRef().scale); + } + }; + template class OpSetAngle : public Interpreter::Opcode0 { @@ -49,7 +59,7 @@ namespace MWScript std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Float angle = runtime[0].mInteger; + Interpreter::Type_Float angle = runtime[0].mFloat; runtime.pop(); if(axis == "X") @@ -67,15 +77,48 @@ namespace MWScript } }; + template + class OpGetAngle : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + if(axis == "X") + { + runtime.push(ptr.getRefData().getPosition().rot[0]); + } + if(axis == "Y") + { + runtime.push(ptr.getRefData().getPosition().rot[1]); + } + if(axis == "Z") + { + runtime.push(ptr.getRefData().getPosition().rot[0]); + } + } + }; + const int opcodeSetScale = 0x2000164; const int opcodeSetScaleExplicit = 0x2000165; const int opcodeSetAngle = 0x2000166; const int opcodeSetAngleExplicit = 0x2000167; + const int opcodeGetScale = 0x2000168; + const int opcodeGetScaleExplicit = 0x2000169; + const int opcodeGetAngle = 0x200016a; + const int opcodeGetAngleExplicit = 0x200016b; void registerExtensions (Compiler::Extensions& extensions) { extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit); - extensions.registerInstruction("setangle","Sl",opcodeSetAngle,opcodeSetAngleExplicit); + extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit); + extensions.registerInstruction("setangle","Sf",opcodeSetAngle,opcodeSetAngleExplicit); + extensions.registerFunction("getangle",'f',"S",opcodeGetAngle,opcodeGetAngleExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -84,6 +127,10 @@ namespace MWScript interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale); interpreter.installSegment5(opcodeSetAngle,new OpSetAngle); interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle); + interpreter.installSegment5(opcodeGetScale,new OpGetScale); + interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale); + interpreter.installSegment5(opcodeGetAngle,new OpGetAngle); + interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c6423563d1..5309fbe40c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -612,8 +612,8 @@ namespace MWWorld MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians(); - ptr.getRefData().getPosition().rot[0] = Ogre::Degree(y).valueRadians(); - ptr.getRefData().getPosition().rot[0] = Ogre::Degree(z).valueRadians(); + ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians(); + ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians(); Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X); Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); From d3a31a24ce860cb907defe2288bf5bfd7a9c871c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 9 Jul 2012 20:53:54 -0700 Subject: [PATCH 33/51] Use proper strings and vectors instead of slice arrays for NIF files Slice arrays use pre-allocated pointers whose memory is managed externally. This is unnecessary and ultimately detrimental since it prevents any kind of data fixup (e.g. little endian to big endian, p[adding handling), and it also makes it difficult to use Ogre data streams. --- components/nif/controlled.hpp | 2 +- components/nif/data.hpp | 10 +-- components/nif/extra.hpp | 4 +- components/nif/nif_file.cpp | 8 +- components/nif/nif_file.hpp | 28 +++++-- components/nif/node.hpp | 8 +- components/nif/record.hpp | 2 +- components/nifbullet/bullet_nif_loader.cpp | 8 +- components/nifogre/ogre_nif_loader.cpp | 93 +++++++++++----------- 9 files changed, 86 insertions(+), 77 deletions(-) diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index 24281146f5..b9d84b58ab 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -53,7 +53,7 @@ public: class Named : public Controlled { public: - Misc::SString name; + std::string name; void read(NIFFile *nif) { diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 0684470ec5..9cdbec537b 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -39,8 +39,8 @@ public: // internal (data is inside the nif itself) texture? bool external; - Misc::SString filename; // In case of external textures - NiPixelDataPtr data; // In case of internal textures + std::string filename; // In case of external textures + NiPixelDataPtr data; // In case of internal textures /* Pixel layout 0 - Palettised @@ -96,7 +96,7 @@ public: class ShapeData : public Record { public: - Misc::FloatArray vertices, normals, colors, uvlist; + std::vector vertices, normals, colors, uvlist; const Vector *center; float radius; @@ -131,7 +131,7 @@ class NiTriShapeData : public ShapeData { public: // Triangles, three vertex indices per triangle - Misc::SliceArray triangles; + std::vector triangles; void read(NIFFile *nif) { @@ -390,7 +390,7 @@ public: { const BoneTrafo *trafo; const Vector4 *unknown; - Misc::SliceArray weights; + std::vector weights; }; struct BoneInfoCopy { diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index ad788661af..e5829fdfc2 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -66,7 +66,7 @@ public: struct TextKey { float time; - Misc::SString text; + std::string text; }; std::vector list; @@ -93,7 +93,7 @@ public: "MRK" - marker, only visible in the editor, not rendered in-game "NCO" - no collision */ - Misc::SString string; + std::string string; void read(NIFFile *nif) { diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 42aa43f8b1..35714bfbeb 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -46,8 +46,8 @@ using namespace Misc; void NIFFile::parse() { // Check the header string - const char* head = getString(40); - if(!begins(head, "NetImmerse File Format")) + std::string head = getString(40); + if(head.compare(0, 22, "NetImmerse File Format") != 0) fail("Invalid NIF header"); // Get BCD version @@ -70,7 +70,7 @@ void NIFFile::parse() for(int i=0;irecType != RC_MISSING); diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index bb6f732599..d3f5f7c06f 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -122,29 +122,41 @@ public: char getByte() { return getType(); } template - Misc::SliceArray getArrayLen(int num) - { return Misc::SliceArray((const X*)inp->getPtr(num*sizeof(X)),num); } + std::vector getArrayLen(int num) + { + std::vector v(num); + memcpy(&v[0], inp->getPtr(num*sizeof(X)), num*sizeof(X)); + return v; + } template - Misc::SliceArray getArray() + std::vector getArray() { int len = getInt(); return getArrayLen(len); } - Misc::SString getString() { return getArray(); } - const Vector *getVector() { return getPtr(); } const Matrix *getMatrix() { return getPtr(); } const Transformation *getTrafo() { return getPtr(); } const Vector4 *getVector4() { return getPtr(); } - Misc::FloatArray getFloatLen(int num) + std::vector getFloatLen(int num) { return getArrayLen(num); } // For fixed-size strings where you already know the size - const char *getString(int size) - { return (const char*)inp->getPtr(size); } + std::string getString(size_t size) + { + std::string str; + str.resize(size); + memcpy(&str[0], inp->getPtr(size), size); + return str.substr(0, str.find('\0')); + } + std::string getString() + { + size_t size = getInt(); + return getString(size); + } }; } // Namespace diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 5a2847b6c2..9d99dbd1df 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -186,10 +186,10 @@ struct NiTriShape : Node NiTriShapeCopy clone() { NiTriShapeCopy copy; - copy.sname = name.toString(); - float *ptr = (float*)data->vertices.ptr; - float *ptrNormals = (float*)data->normals.ptr; - int numVerts = data->vertices.length / 3; + copy.sname = name; + float *ptr = (float*)&data->vertices[0]; + float *ptrNormals = (float*)&data->normals[0]; + int numVerts = data->vertices.size() / 3; for(int i = 0; i < numVerts; i++) { float *current = (float*) (ptr + i * 3); diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 06fdce55e7..84f253eb89 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -90,7 +90,7 @@ struct Record { // Record type and type name int recType; - Misc::SString recName; + std::string recName; Record() : recType(RC_MISSING) {} diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 30cb4562d0..9f31a3eed5 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -124,7 +124,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) if (node == NULL) { warn("First record in file was not a node, but a " + - r->recName.toString() + ". Skipping file."); + r->recName + ". Skipping file."); return; } @@ -292,10 +292,10 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags Nif::NiTriShapeData *data = shape->data.getPtr(); - float* vertices = (float*)data->vertices.ptr; - unsigned short* triangles = (unsigned short*)data->triangles.ptr; + float* vertices = (float*)&data->vertices[0]; + unsigned short* triangles = (unsigned short*)&data->triangles[0]; - for(unsigned int i=0; i < data->triangles.length; i = i+3) + for(unsigned int i=0; i < data->triangles.size(); 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); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 895c51a0d9..55dbba5185 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -399,7 +399,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std { // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); - SubMesh *sub = mesh->createSubMesh(shape->name.toString()); + SubMesh *sub = mesh->createSubMesh(shape->name); int nextBuf = 0; @@ -407,7 +407,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std // great. // Add vertices - int numVerts = data->vertices.length / 3; + int numVerts = data->vertices.size() / 3; sub->vertexData = new VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; @@ -422,12 +422,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std if(flip) { - float *datamod = new float[data->vertices.length]; + float *datamod = new float[data->vertices.size()]; //std::cout << "Shape" << shape->name.toString() << "\n"; for(int i = 0; i < numVerts; i++) { int index = i * 3; - const float *pos = data->vertices.ptr + index; + const float *pos = &data->vertices[index]; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = mTransform * original; mBoundingBox.merge(original); @@ -440,14 +440,14 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std } else { - vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false); + vbuf->writeData(0, vbuf->getSizeInBytes(), &data->vertices[0], false); } VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); - if (data->normals.length) + if (data->normals.size()) { decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( @@ -459,11 +459,11 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); - float *datamod = new float[data->normals.length]; + float *datamod = new float[data->normals.size()]; for(int i = 0; i < numVerts; i++) { int index = i * 3; - const float *pos = data->normals.ptr + index; + const float *pos = &data->normals[index]; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = rotation * original; if (mNormaliseNormals) @@ -481,16 +481,16 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std } else { - vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false); + vbuf->writeData(0, vbuf->getSizeInBytes(), &data->normals[0], false); } bind->setBinding(nextBuf++, vbuf); } // Vertex colors - if (data->colors.length) + if (data->colors.size()) { - const float *colors = data->colors.ptr; + const float *colors = &data->colors[0]; RenderSystem* rs = Root::getSingleton().getRenderSystem(); std::vector colorsRGB(numVerts); RGBA *pColour = &colorsRGB.front(); @@ -508,7 +508,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std bind->setBinding(nextBuf++, vbuf); } - if (data->uvlist.length) + if (data->uvlist.size()) { decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); @@ -518,12 +518,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std if(flip) { - float *datamod = new float[data->uvlist.length]; + float *datamod = new float[data->uvlist.size()]; - for(unsigned int i = 0; i < data->uvlist.length; i+=2){ - float x = *(data->uvlist.ptr + i); + for(unsigned int i = 0; i < data->uvlist.size(); i+=2){ + float x = data->uvlist[i]; - float y = *(data->uvlist.ptr + i + 1); + float y = data->uvlist[i + 1]; datamod[i] =x; datamod[i + 1] =y; @@ -532,13 +532,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std delete [] datamod; } else - vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false); + vbuf->writeData(0, vbuf->getSizeInBytes(), &data->uvlist[0], false); bind->setBinding(nextBuf++, vbuf); } // Triangle faces - The total number of triangle points - int numFaces = data->triangles.length; - + int numFaces = data->triangles.size(); if (numFaces) { @@ -558,7 +557,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std for (size_t i = 0; i < sub->indexData->indexCount; i+=3) { - const short *pos = data->triangles.ptr + index; + const short *pos = &data->triangles[index]; uint16 i0 = (uint16) *(pos+0); uint16 i1 = (uint16) *(pos+1); uint16 i2 = (uint16) *(pos+2); @@ -578,7 +577,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std } else - ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); + ibuf->writeData(0, ibuf->getSizeInBytes(), &data->triangles[0], false); sub->indexData->indexBuffer = ibuf; } @@ -706,8 +705,6 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou NiSourceTexture *st = t->textures[0].texture.getPtr(); if (st->external) { - SString tname = st->filename; - /* findRealTexture checks if the file actually exists. If it doesn't, and the name ends in .tga, it will try replacing the extension with .dds instead @@ -721,7 +718,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou problem since all the nif data is stored in a local throwaway buffer. */ - texName = "textures\\" + tname.toString(); + texName = "textures\\" + st->filename; findRealTexture(texName); } else warn("Found internal texture, ignoring."); @@ -795,9 +792,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou level. */ NiTriShapeData *data = shape->data.getPtr(); - int numVerts = data->vertices.length / 3; + int numVerts = data->vertices.size() / 3; - float *ptr = (float*)data->vertices.ptr; + float *ptr = (float*)&data->vertices[0]; float *optr = ptr; std::list vertexBoneAssignments; @@ -828,7 +825,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou std::vector vertexPosOriginal(numVerts, Ogre::Vector3::ZERO); std::vector vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO); - float *ptrNormals = (float*)data->normals.ptr; + float *ptrNormals = (float*)&data->normals[0]; //the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex] //the first one contains a link to the bone, the second vertex transformation //relative to the bone @@ -849,13 +846,13 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou { if(mSkel.isNull()) { - std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name.toString() << std::endl; + std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name << std::endl; break; } //get the bone from bones array of skindata - if(!mSkel->hasBone(shape->skin->bones[boneIndex].name.toString())) + if(!mSkel->hasBone(shape->skin->bones[boneIndex].name)) std::cout << "We don't have this bone"; - bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString()); + bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name); // final_vector = old_vector + old_rotation*new_vector*old_scale @@ -863,19 +860,19 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou Nif::NiSkinData::BoneInfoCopy boneinfocopy; boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation); boneinfocopy.trafo.trans = convertVector3(it->trafo->trans); - boneinfocopy.bonename = shape->skin->bones[boneIndex].name.toString(); + boneinfocopy.bonename = shape->skin->bones[boneIndex].name; boneinfocopy.bonehandle = bonePtr->getHandle(); copy.boneinfo.push_back(boneinfocopy); - for (unsigned int i=0; iweights.length; i++) + for (unsigned int i=0; iweights.size(); i++) { vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * convertVector3(it->trafo->trans); vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation); - unsigned int verIndex = (it->weights.ptr + i)->vertex; + unsigned int verIndex = it->weights[i].vertex; //boneinfo.weights.push_back(*(it->weights.ptr + i)); Nif::NiSkinData::IndividualWeight ind; - ind.weight = (it->weights.ptr + i)->weight; + ind.weight = it->weights[i].weight; ind.boneinfocopyindex = copy.boneinfo.size() - 1; if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end()) { @@ -893,7 +890,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou { //apply transformation to the vertices Vector3 absVertPos = vecPos + vecRot * Vector3(ptr + verIndex *3); - absVertPos = absVertPos * (it->weights.ptr + i)->weight; + absVertPos = absVertPos * it->weights[i].weight; vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3); mBoundingBox.merge(absVertPos); @@ -903,10 +900,10 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou //apply rotation to the normals (not every vertex has a normal) //FIXME: I guessed that vertex[i] = normal[i], is that true? - if (verIndex < data->normals.length) + if (verIndex < data->normals.size()) { Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3); - absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; + absNormalsPos = absNormalsPos * it->weights[i].weight; vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3); for (int j=0; j<3; j++) @@ -918,7 +915,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou else { Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex]; - absVertPos = absVertPos * (it->weights.ptr + i)->weight; + absVertPos = absVertPos * it->weights[i].weight; Vector3 old = Vector3(ptr + verIndex *3); absVertPos = absVertPos + old; @@ -929,10 +926,10 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou //apply rotation to the normals (not every vertex has a normal) //FIXME: I guessed that vertex[i] = normal[i], is that true? - if (verIndex < data->normals.length) + if (verIndex < data->normals.size()) { Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex]; - absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; + absNormalsPos = absNormalsPos * it->weights[i].weight; Vector3 oldNormal = Vector3(ptrNormals + verIndex *3); absNormalsPos = absNormalsPos + oldNormal; @@ -945,7 +942,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou VertexBoneAssignment vba; vba.boneIndex = bonePtr->getHandle(); vba.vertexIndex = verIndex; - vba.weight = (it->weights.ptr + i)->weight; + vba.weight = it->weights[i].weight; vertexBoneAssignments.push_back(vba); @@ -981,9 +978,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou } // Remember to rotate all the vertex normals as well - if (data->normals.length) + if (data->normals.size()) { - ptr = (float*)data->normals.ptr; + ptr = (float*)&data->normals[0]; for (int i=0; i::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++) { - std::string text = textiter->text.toString(); + std::string text = textiter->text; replace(text.begin(), text.end(), '\n', '/'); @@ -1138,7 +1135,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, if (!mSkel.isNull()) //if there is a skeleton { - std::string name = node->name.toString(); + std::string name = node->name; // Quick-n-dirty workaround for the fact that several // bones may have the same name. @@ -1192,7 +1189,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, } else if (node->recType == RC_NiTriShape && bNiTri) { - std::string nodename = node->name.toString(); + std::string nodename = node->name; if (triname == "") { @@ -1334,7 +1331,7 @@ void NIFLoader::loadResource(Resource *resource) if (node == NULL) { warn("First record in file was not a node, but a " + - r->recName.toString() + ". Skipping file."); + r->recName + ". Skipping file."); return; } @@ -1358,7 +1355,7 @@ void NIFLoader::loadResource(Resource *resource) if (f->timeStart >= 10000000000000000.0f) continue; - data->setBonename(o->name.toString()); + data->setBonename(o->name); data->setStartTime(f->timeStart); data->setStopTime(f->timeStop); From 0143cacd2bebdf7a13b5e2539e54b2f3da8959bd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 9 Jul 2012 21:35:36 -0700 Subject: [PATCH 34/51] Avoid returning pointers from NIFFile --- components/nif/data.hpp | 12 +++++----- components/nif/effect.hpp | 4 ++-- components/nif/nif_file.cpp | 2 +- components/nif/nif_file.hpp | 14 ++++++----- components/nif/nif_types.hpp | 4 ++-- components/nif/node.hpp | 14 +++++------ components/nif/property.hpp | 4 ++-- components/nifbullet/bullet_nif_loader.cpp | 2 +- components/nifogre/ogre_nif_loader.cpp | 28 +++++++++++----------- 9 files changed, 43 insertions(+), 41 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 9cdbec537b..a9a5895f4f 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -97,7 +97,7 @@ class ShapeData : public Record { public: std::vector vertices, normals, colors, uvlist; - const Vector *center; + Vector center; float radius; void read(NIFFile *nif) @@ -388,8 +388,8 @@ public: struct BoneInfo { - const BoneTrafo *trafo; - const Vector4 *unknown; + BoneTrafo trafo; + Vector4 unknown; std::vector weights; }; struct BoneInfoCopy @@ -406,7 +406,7 @@ public: unsigned int boneinfocopyindex; }; - const BoneTrafo *trafo; + BoneTrafo trafo; std::vector bones; void read(NIFFile *nif) @@ -414,7 +414,7 @@ public: assert(sizeof(BoneTrafo) == 4*(9+3+1)); assert(sizeof(VertWeight) == 6); - trafo = nif->getPtr(); + trafo = nif->getType(); int boneNum = nif->getInt(); nif->getInt(); // -1 @@ -424,7 +424,7 @@ public: { BoneInfo &bi = bones[i]; - bi.trafo = nif->getPtr(); + bi.trafo = nif->getType(); bi.unknown = nif->getVector4(); // Number of vertex weights diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index bac412c766..6ecc7c61ae 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -42,7 +42,7 @@ struct NiLight : Effect Vector diffuse; Vector specular; }; - const SLight *light; + SLight light; void read(NIFFile *nif) { @@ -50,7 +50,7 @@ struct NiLight : Effect nif->getInt(); // 1 nif->getInt(); // 1? - light = nif->getPtr(); + light = nif->getType(); } }; diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 35714bfbeb..36badbf0d8 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -201,7 +201,7 @@ void NiSkinInstance::post(NIFFile *nif) if(bnum != data->bones.size()) nif->fail("Mismatch in NiSkinData bone count"); - root->makeRootBone(data->trafo); + root->makeRootBone(&data->trafo); for(size_t i=0; igetPtr(size); } - template const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); } - template X getType() { return *getPtr(); } + template X getType() + { + return *(const X*)inp->getPtr(sizeof(X)); + } unsigned short getShort() { return getType(); } int getInt() { return getType(); } float getFloat() { return getType(); } @@ -136,10 +138,10 @@ public: return getArrayLen(len); } - const Vector *getVector() { return getPtr(); } - const Matrix *getMatrix() { return getPtr(); } - const Transformation *getTrafo() { return getPtr(); } - const Vector4 *getVector4() { return getPtr(); } + Vector getVector() { return getType(); } + Matrix getMatrix() { return getType(); } + Transformation getTrafo() { return getType(); } + Vector4 getVector4() { return getType(); } std::vector getFloatLen(int num) { return getArrayLen(num); } diff --git a/components/nif/nif_types.hpp b/components/nif/nif_types.hpp index ee796cc991..41900a14ed 100644 --- a/components/nif/nif_types.hpp +++ b/components/nif/nif_types.hpp @@ -60,7 +60,7 @@ struct Transformation float scale; Vector velocity; - static const Transformation* getIdentity() + static const Transformation& getIdentity() { static Transformation identity; static bool iset = false; @@ -73,7 +73,7 @@ struct Transformation iset = true; } - return &identity; + return identity; } }; #pragma pack(pop) diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 9d99dbd1df..8a6af57774 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -42,14 +42,14 @@ class Node : public Named public: // Node flags. Interpretation depends somewhat on the type of node. int flags; - const Transformation *trafo; + Transformation trafo; PropertyList props; // Bounding box info bool hasBounds; - const Vector *boundPos; - const Matrix *boundRot; - const Vector *boundXYZ; // Box size + Vector boundPos; + Matrix boundRot; + Vector boundXYZ; // Box size void read(NIFFile *nif) { @@ -103,7 +103,7 @@ public: void makeBone(short ind, const NiSkinData::BoneInfo &bi) { boneInfo = &bi; - boneTrafo = bi.trafo; + boneTrafo = &bi.trafo; boneIndex = ind; } }; @@ -219,13 +219,13 @@ struct NiCamera : Node // Level of detail modifier float LOD; }; - const Camera *cam; + Camera cam; void read(NIFFile *nif) { Node::read(nif); - nif->getPtr(); + cam = nif->getType(); nif->getInt(); // -1 nif->getInt(); // 0 diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 619e3db0e0..8485d978f8 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -155,12 +155,12 @@ typedef Property NiWireframeProperty; template struct StructPropT : Property { - const T* data; + T data; void read(NIFFile *nif) { Property::read(nif); - data = nif->getPtr(); + data = nif->getType(); } }; diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 9f31a3eed5..f32b5e8966 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -226,7 +226,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, Ogre::Vector3 finalPos; float finalScale; - Nif::Transformation &final = *((Nif::Transformation*)node->trafo); + Nif::Transformation &final = node->trafo; Ogre::Vector3 nodePos = getVector(&final); Ogre::Matrix3 nodeRot = getMatrix(&final); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 55dbba5185..616e462fd8 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -730,7 +730,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou if (a) { alphaFlags = a->flags; - alphaTest = a->data->threshold; + alphaTest = a->data.threshold; } // Material @@ -745,7 +745,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou if (m) { // Use NiMaterialProperty data to create the data - const S_MaterialProperty *d = m->data; + const S_MaterialProperty *d = &m->data; std::multimap::iterator itr = MaterialMap.find(texName); std::multimap::iterator lastElement; @@ -858,17 +858,17 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou Nif::NiSkinData::BoneInfoCopy boneinfocopy; - boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation); - boneinfocopy.trafo.trans = convertVector3(it->trafo->trans); + boneinfocopy.trafo.rotation = convertRotation(it->trafo.rotation); + boneinfocopy.trafo.trans = convertVector3(it->trafo.trans); boneinfocopy.bonename = shape->skin->bones[boneIndex].name; boneinfocopy.bonehandle = bonePtr->getHandle(); copy.boneinfo.push_back(boneinfocopy); for (unsigned int i=0; iweights.size(); i++) { vecPos = bonePtr->_getDerivedPosition() + - bonePtr->_getDerivedOrientation() * convertVector3(it->trafo->trans); + bonePtr->_getDerivedOrientation() * convertVector3(it->trafo.trans); - vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation); + vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo.rotation); unsigned int verIndex = it->weights[i].vertex; //boneinfo.weights.push_back(*(it->weights.ptr + i)); Nif::NiSkinData::IndividualWeight ind; @@ -959,9 +959,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou copy.boneSequence = boneSequence; // Rotate, scale and translate all the vertices, - const Matrix &rot = shape->trafo->rotation; - const Vector &pos = shape->trafo->pos; - float scale = shape->trafo->scale; + const Matrix &rot = shape->trafo.rotation; + const Vector &pos = shape->trafo.pos; + float scale = shape->trafo.scale; copy.trafo.trans = convertVector3(original.pos); copy.trafo.rotation = convertRotation(original.rotation); @@ -1148,19 +1148,19 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, parentBone->addChild(bone); bone->setInheritOrientation(true); - bone->setPosition(convertVector3(node->trafo->pos)); - bone->setOrientation(convertRotation(node->trafo->rotation)); + bone->setPosition(convertVector3(node->trafo.pos)); + bone->setOrientation(convertRotation(node->trafo.rotation)); } } } - Transformation original = *(node->trafo); + Transformation original = node->trafo; // Apply the parent transformation to this node. We overwrite the // existing data with the final transformation. 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); + Transformation &final = node->trafo; // For both position and rotation we have that: // final_vector = old_vector + old_rotation*new_vector*old_scale @@ -1184,7 +1184,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, { if (list.has(i)) - handleNode(&list[i], flags, node->trafo, bounds, bone, boneSequence); + handleNode(&list[i], flags, &node->trafo, bounds, bone, boneSequence); } } else if (node->recType == RC_NiTriShape && bNiTri) From b3aa453f9a2e005fb6ce203b56dffa612135a23c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 9 Jul 2012 22:02:12 -0700 Subject: [PATCH 35/51] Use Ogre data streams for loading NIFs --- components/nif/nif_file.hpp | 38 ++++++++-------------- components/nifbullet/bullet_nif_loader.cpp | 14 +------- components/nifbullet/bullet_nif_loader.hpp | 12 +------ components/nifogre/ogre_nif_loader.cpp | 24 +++----------- components/nifogre/ogre_nif_loader.hpp | 7 ---- 5 files changed, 21 insertions(+), 74 deletions(-) diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 59ba3a5b92..a2246e00e2 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -24,9 +24,8 @@ #ifndef _NIF_FILE_H_ #define _NIF_FILE_H_ -#include -#include -#include +#include +#include #include #include @@ -36,8 +35,6 @@ #include "record.hpp" #include "nif_types.hpp" -using namespace Mangle::Stream; - namespace Nif { @@ -51,7 +48,7 @@ class NIFFile int ver; /// Input stream - StreamPtr inp; + Ogre::DataStreamPtr inp; /// File name, used for error messages std::string filename; @@ -72,22 +69,10 @@ public: } /// Open a NIF stream. The name is used for error messages. - NIFFile(StreamPtr nif, const std::string &name) + NIFFile(const std::string &name) : filename(name) { - /* Load the entire file into memory. This allows us to use - direct pointers to the data arrays in the NIF, instead of - individually allocating and copying each one. - - The NIF data is only stored temporarily in memory, since once - the mesh data is loaded it is siphoned into OGRE and - deleted. For that reason, we might improve this further and - use a shared region/pool based allocation scheme in the - future, especially since only one NIFFile will ever be loaded - at any given time. - */ - inp = StreamPtr(new BufferStream(nif)); - + inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); parse(); } @@ -112,11 +97,14 @@ public: Parser functions ****************************************************/ - void skip(size_t size) { inp->getPtr(size); } + void skip(size_t size) { inp->skip(size); } template X getType() { - return *(const X*)inp->getPtr(sizeof(X)); + X obj; + if(inp->read(&obj, sizeof(X)) != sizeof(X)) + fail("Failed to read from NIF"); + return obj; } unsigned short getShort() { return getType(); } int getInt() { return getType(); } @@ -127,7 +115,8 @@ public: std::vector getArrayLen(int num) { std::vector v(num); - memcpy(&v[0], inp->getPtr(num*sizeof(X)), num*sizeof(X)); + if(inp->read(&v[0], num*sizeof(X)) != num*sizeof(X)) + fail("Failed to read from NIF"); return v; } @@ -151,7 +140,8 @@ public: { std::string str; str.resize(size); - memcpy(&str[0], inp->getPtr(size), size); + if(inp->read(&str[0], size) != size) + fail("Failed to read from NIF"); return str.substr(0, str.find('\0')); } std::string getString() diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index f32b5e8966..ae9ac94c26 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -25,7 +25,6 @@ http://www.gnu.org/licenses/ . #include #include -#include #include "../nif/nif_file.hpp" #include "../nif/node.hpp" #include "../nif/data.hpp" @@ -47,13 +46,11 @@ typedef unsigned char ubyte; using namespace std; using namespace Ogre; using namespace Nif; -using namespace Mangle::VFS; using namespace NifBullet; ManualBulletShapeLoader::~ManualBulletShapeLoader() { - delete vfs; } Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr) @@ -94,20 +91,11 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) mTriMesh = new btTriangleMesh(); - if (!vfs) vfs = new OgreVFS(resourceGroup); - - if (!vfs->isFile(resourceName)) - { - warn("File not found."); - return; - } - // Load the NIF. TODO: Wrap this in a try-catch block once we're out // of the early stages of development. Right now we WANT to catch // every error as early and intrusively as possible, as it's most // likely a sign of incomplete code rather than faulty input. - Nif::NIFFile nif(vfs->open(resourceName), resourceName); - + Nif::NIFFile nif(resourceName); if (nif.numRecords() < 1) { warn("Found no records in NIF."); diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index ed3aceac46..5a33074c9e 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -50,14 +50,6 @@ namespace Nif class Matrix; } -namespace Mangle -{ - namespace VFS - { - class OgreVFS; - } -} - namespace NifBullet { @@ -68,7 +60,7 @@ class ManualBulletShapeLoader : public BulletShapeLoader { public: - ManualBulletShapeLoader():resourceGroup("General"){vfs = 0;} + ManualBulletShapeLoader():resourceGroup("General"){} virtual ~ManualBulletShapeLoader(); void warn(std::string msg) @@ -119,8 +111,6 @@ private: */ void handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly); - Mangle::VFS::OgreVFS *vfs; - std::string resourceName; std::string resourceGroup; diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 616e462fd8..64a1e0871d 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -379,16 +379,12 @@ String NIFLoader::getUniqueName(const String &input) // is lost in that case. void NIFLoader::findRealTexture(String &texName) { - assert(vfs); - if (vfs->isFile(texName)) return; - - int len = texName.size(); - if (len < 4) return; + if(Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName)) + return; // Change texture extension to .dds - texName[len-3] = 'd'; - texName[len-2] = 'd'; - texName[len-1] = 's'; + String::size_type pos = texName.rfind('.'); + texName.replace(pos, texName.length(), ".dds"); } //Handle node at top @@ -1290,9 +1286,6 @@ void NIFLoader::loadResource(Resource *resource) { calculateTransform(); } - // Set up the VFS if it hasn't been done already - if (!vfs) vfs = new OgreVFS(resourceGroup); - // Get the mesh mesh = dynamic_cast(resource); assert(mesh); @@ -1301,12 +1294,6 @@ void NIFLoader::loadResource(Resource *resource) resourceName = mesh->getName(); //std::cout << resourceName << "\n"; - if (!vfs->isFile(resourceName)) - { - warn("File "+resourceName+" not found."); - return; - } - // Helper that computes bounding boxes for us. BoundsFinder bounds; @@ -1314,8 +1301,7 @@ void NIFLoader::loadResource(Resource *resource) // of the early stages of development. Right now we WANT to catch // every error as early and intrusively as possible, as it's most // likely a sign of incomplete code rather than faulty input. - NIFFile nif(vfs->open(resourceName), resourceName); - + NIFFile nif(resourceName); if (nif.numRecords() < 1) { warn("Found no records in NIF."); diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index d73948fa82..55915b3102 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -154,13 +154,6 @@ class NIFLoader : Ogre::ManualResourceLoader return resourceName + ".skel"; } - // This is the interface to the Ogre resource system. It allows us to - // load NIFs from BSAs, in the file system and in any other place we - // tell Ogre to look (eg. in zip or rar files.) It's also used to - // check for the existence of texture files, so we can exchange the - // extension from .tga to .dds if the texture is missing. - Mangle::VFS::OgreVFS *vfs; - std::string verbosePath; std::string resourceName; std::string resourceGroup; From 98ae7168b1fe10ec86f2e8810d06448dc0362669 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 00:24:18 -0700 Subject: [PATCH 36/51] Fix double-incrementing a pointer --- components/nifogre/ogre_nif_loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 64a1e0871d..ec54319c18 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -968,7 +968,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou for (int i=0; i Date: Tue, 10 Jul 2012 00:27:13 -0700 Subject: [PATCH 37/51] Remove NIFFile::getType --- components/nif/data.hpp | 18 ++++-- components/nif/effect.hpp | 10 ++- components/nif/extra.hpp | 2 +- components/nif/nif_file.hpp | 124 ++++++++++++++++++++++++++++++------ components/nif/node.hpp | 19 +++++- components/nif/property.hpp | 23 ++++++- 6 files changed, 166 insertions(+), 30 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index a9a5895f4f..1b5fa029b0 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -105,16 +105,16 @@ public: int verts = nif->getShort(); if(nif->getInt()) - vertices = nif->getFloatLen(verts*3); + vertices = nif->getArrayLen(verts*3); if(nif->getInt()) - normals = nif->getFloatLen(verts*3); + normals = nif->getArrayLen(verts*3); center = nif->getVector(); radius = nif->getFloat(); if(nif->getInt()) - colors = nif->getFloatLen(verts*4); + colors = nif->getArrayLen(verts*4); int uvs = nif->getShort(); @@ -123,7 +123,7 @@ public: uvs &= 0x3f; if(nif->getInt()) - uvlist = nif->getFloatLen(uvs*verts*2); + uvlist = nif->getArrayLen(uvs*verts*2); } }; @@ -181,7 +181,7 @@ public: if(nif->getInt()) { // Particle sizes - nif->getFloatLen(activeCount); + nif->getArrayLen(activeCount); } } }; @@ -414,7 +414,9 @@ public: assert(sizeof(BoneTrafo) == 4*(9+3+1)); assert(sizeof(VertWeight) == 6); - trafo = nif->getType(); + trafo.rotation = nif->getMatrix(); + trafo.trans = nif->getVector(); + trafo.scale = nif->getFloat(); int boneNum = nif->getInt(); nif->getInt(); // -1 @@ -424,7 +426,9 @@ public: { BoneInfo &bi = bones[i]; - bi.trafo = nif->getType(); + bi.trafo.rotation = nif->getMatrix(); + bi.trafo.trans = nif->getVector(); + bi.trafo.scale = nif->getFloat(); bi.unknown = nif->getVector4(); // Number of vertex weights diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 6ecc7c61ae..f48049ec45 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -41,6 +41,14 @@ struct NiLight : Effect Vector ambient; Vector diffuse; Vector specular; + + void read(NIFFile *nif) + { + nif->load(dimmer); + ambient = nif->getVector(); + diffuse = nif->getVector(); + specular = nif->getVector(); + } }; SLight light; @@ -50,7 +58,7 @@ struct NiLight : Effect nif->getInt(); // 1 nif->getInt(); // 1? - light = nif->getType(); + light.read(nif); } }; diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index e5829fdfc2..5615d833ef 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -56,7 +56,7 @@ public: /*int i =*/ nif->getInt(); int s = nif->getShort(); // number of vertices - nif->getFloatLen(s); // vertex weights I guess + nif->getArrayLen(s); // vertex weights I guess } }; diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index a2246e00e2..c4b1382324 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -99,20 +99,70 @@ public: void skip(size_t size) { inp->skip(size); } - template X getType() + uint32_t read_le32() { - X obj; - if(inp->read(&obj, sizeof(X)) != sizeof(X)) - fail("Failed to read from NIF"); - return obj; + uint8_t buffer[4]; + if(inp->read(buffer, 4) != 4) return 0; + return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); + } + uint16_t read_le16() + { + uint8_t buffer[2]; + if(inp->read(buffer, 2) != 2) return 0; + return buffer[0] | (buffer[1]<<8); + } + uint8_t read_byte() + { + uint8_t byte; + if(inp->read(&byte, 1) != 1) return 0; + return byte; + } + std::string read_string(size_t length) + { + std::string str; + str.resize(length); + if(inp->read(&str[0], length) != length) + return std::string(); + return str.substr(0, str.find('\0')); } - unsigned short getShort() { return getType(); } - int getInt() { return getType(); } - float getFloat() { return getType(); } - char getByte() { return getType(); } - template - std::vector getArrayLen(int num) + + char& load(char &c) { c = read_byte(); return c; } + unsigned char& load(unsigned char &c) { c = read_byte(); return c; } + short& load(short &s) { s = read_le16(); return s; } + unsigned short& load(unsigned short &s) { s = read_le16(); return s; } + int& load(int &i) { i = read_le32(); return i; } + unsigned int& load(unsigned int &i) { i = read_le32(); return i; } + float& load(float &f) + { + union { + int i; + float f; + } u = { read_le32() }; + f = u.f; + return f; + } + + template + T* load(T (&a)[N]) + { + for(size_t i = 0;i < N;i++) + load(a[i]); + return a; + } + + template + std::vector& load(std::vector &v, size_t size) + { + v.resize(size); + for(size_t i = 0;i < size;i++) + load(v[i]); + return v; + } + + + template + std::vector getArrayLen(size_t num) { std::vector v(num); if(inp->read(&v[0], num*sizeof(X)) != num*sizeof(X)) @@ -120,20 +170,47 @@ public: return v; } - template + template std::vector getArray() { - int len = getInt(); + size_t len = read_le32(); return getArrayLen(len); } - Vector getVector() { return getType(); } - Matrix getMatrix() { return getType(); } - Transformation getTrafo() { return getType(); } - Vector4 getVector4() { return getType(); } + char getByte() { char c; return load(c); } + unsigned short getShort() { unsigned short s; return load(s); } + int getInt() { int i; return load(i); } + float getFloat() { float f; return load(f); } + Vector getVector() + { + Vector v; + load(v.array); + return v; + } + Vector4 getVector4() + { + Vector4 v; + load(v.array); + return v; + } + Matrix getMatrix() + { + Matrix m; + m.v[0] = getVector(); + m.v[1] = getVector(); + m.v[2] = getVector(); + return m; + } + Transformation getTrafo() + { + Transformation t; + t.pos = getVector(); + t.rotation = getMatrix(); + load(t.scale); + t.velocity = getVector(); + return t; + } - std::vector getFloatLen(int num) - { return getArrayLen(num); } // For fixed-size strings where you already know the size std::string getString(size_t size) @@ -151,5 +228,14 @@ public: } }; +template<> +inline std::vector NIFFile::getArrayLen(size_t num) +{ + std::vector v(num); + for(size_t i = 0;i < num;i++) + load(v[i]); + return v; +} + } // Namespace #endif diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 8a6af57774..d5cd8fe824 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -218,6 +218,23 @@ struct NiCamera : Node // Level of detail modifier float LOD; + + void read(NIFFile *nif) + { + nif->load(left); + nif->load(right); + nif->load(top); + nif->load(bottom); + nif->load(nearDist); + nif->load(farDist); + + nif->load(vleft); + nif->load(vright); + nif->load(vtop); + nif->load(vbottom); + + nif->load(LOD); + } }; Camera cam; @@ -225,7 +242,7 @@ struct NiCamera : Node { Node::read(nif); - cam = nif->getType(); + cam.read(nif); nif->getInt(); // -1 nif->getInt(); // 0 diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 8485d978f8..87e3ae5f23 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -160,7 +160,7 @@ struct StructPropT : Property void read(NIFFile *nif) { Property::read(nif); - data = nif->getType(); + data.read(nif); } }; @@ -169,6 +169,16 @@ struct S_MaterialProperty // The vector components are R,G,B Vector ambient, diffuse, specular, emissive; float glossiness, alpha; + + void read(NIFFile *nif) + { + ambient = nif->getVector(); + diffuse = nif->getVector(); + specular = nif->getVector(); + emissive = nif->getVector(); + nif->load(glossiness); + nif->load(alpha); + } }; struct S_VertexColorProperty @@ -183,6 +193,12 @@ struct S_VertexColorProperty 1 - lighting emmisive ambient/diffuse */ int vertmode, lightmode; + + void read(NIFFile *nif) + { + nif->load(vertmode); + nif->load(lightmode); + } }; struct S_AlphaProperty @@ -234,6 +250,11 @@ struct S_AlphaProperty // Tested against when certain flags are set (see above.) unsigned char threshold; + + void read(NIFFile *nif) + { + nif->load(threshold); + } }; typedef StructPropT NiAlphaProperty; From 410b69355539f9ad5d328e0fdd0b4b21b5962d98 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 10 Jul 2012 11:15:46 +0200 Subject: [PATCH 38/51] setAngle improvement --- apps/openmw/mwclass/npc.cpp | 7 +++++++ apps/openmw/mwclass/npc.hpp | 2 ++ .../openmw/mwscript/transformationextensions.cpp | 16 ++++++++++------ apps/openmw/mwworld/worldimp.cpp | 4 ++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ab4e2d5e6c..0d2efcd9ee 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -347,4 +347,11 @@ namespace MWClass return weight; } + + void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const + { + y = 0; + x = 0; + std::cout << "dfdfdfdfnzdofnmqsldgnmqskdhblqkdbv lqksdf"; + } } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 4cb733977e..f50ed2159a 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -76,6 +76,8 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. + virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const; + static void registerSelf(); }; } diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 41eba4a994..2ea80c0d88 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -62,17 +62,21 @@ namespace MWScript Interpreter::Type_Float angle = runtime[0].mFloat; runtime.pop(); + float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); + float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); + float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees(); + if(axis == "X") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,0,0); + MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az); } if(axis == "Y") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,0,angle,0); + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az); } if(axis == "Z") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,0,0,angle); + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle); } } }; @@ -91,15 +95,15 @@ namespace MWScript if(axis == "X") { - runtime.push(ptr.getRefData().getPosition().rot[0]); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()); } if(axis == "Y") { - runtime.push(ptr.getRefData().getPosition().rot[1]); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()); } if(axis == "Z") { - runtime.push(ptr.getRefData().getPosition().rot[0]); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()); } } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5309fbe40c..1e1fae1548 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -602,7 +602,7 @@ namespace MWWorld MWWorld::Class::get(ptr).adjustScale(ptr,scale); ptr.getCellRef().scale = scale; - scale = scale/ptr.getRefData().getBaseNode()->getScale().x; + //scale = scale/ptr.getRefData().getBaseNode()->getScale().x; ptr.getRefData().getBaseNode()->setScale(scale,scale,scale); mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); } @@ -618,7 +618,7 @@ namespace MWWorld Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X); Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); - ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); + ptr.getRefData().getBaseNode()->setOrientation(rotz*rotx*roty); mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); } From ca37706b3406c1b88ee1c754097b4a917353679b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 02:38:35 -0700 Subject: [PATCH 39/51] Use Ogre types for Matrix and Vector objects --- components/nif/data.hpp | 54 ++--- components/nif/effect.hpp | 6 +- components/nif/nif_file.hpp | 55 +++-- components/nif/nif_types.hpp | 40 +-- components/nif/node.hpp | 6 +- components/nif/property.hpp | 2 +- components/nifbullet/bullet_nif_loader.cpp | 20 +- components/nifbullet/bullet_nif_loader.hpp | 6 +- components/nifogre/ogre_nif_loader.cpp | 269 +++++++++------------ components/nifogre/ogre_nif_loader.hpp | 20 +- 10 files changed, 192 insertions(+), 286 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 1b5fa029b0..667e77ffd5 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -97,7 +97,7 @@ class ShapeData : public Record { public: std::vector vertices, normals, colors, uvlist; - Vector center; + Ogre::Vector3 center; float radius; void read(NIFFile *nif) @@ -198,7 +198,7 @@ public: // Rotation quaternions. I THINK activeCount is correct here, // but verts (vertex number) might also be correct, if there is // any case where the two don't match. - nif->getArrayLen(activeCount); + nif->skip(activeCount * 4*sizeof(float)); } } }; @@ -244,7 +244,7 @@ public: if(count) { nif->getInt(); // always 2 - nif->getArrayLen(count); // Really one time float + one vector + nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector } } // Always 0 @@ -260,7 +260,7 @@ public: { int count = nif->getInt(); nif->getInt(); // always 2 - nif->getArrayLen(count); // Really one time float + one vector + nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector } }; @@ -309,7 +309,7 @@ public: struct ColorData { float time; - Vector4 rgba; + Ogre::Vector4 rgba; }; void read(NIFFile *nif) @@ -318,25 +318,23 @@ public: nif->getInt(); // always 1 // Skip the data - assert(sizeof(ColorData) == 4*5); - nif->skip(sizeof(ColorData) * count); + nif->skip(count * 5*sizeof(float)); } }; class NiVisData : public Record { public: + struct VisData { + float time; + char isSet; + }; + void read(NIFFile *nif) { int count = nif->getInt(); - /* - Each VisData consists of: - float time; - byte isSet; - If you implement this, make sure you use a packed struct - (sizeof==5), or read each element individually. - */ + /* Skip VisData */ nif->skip(count*5); } }; @@ -361,16 +359,11 @@ public: class NiSkinData : public Record { public: - // This is to make sure the structs are packed, ie. that the - // compiler doesn't mess them up with extra alignment bytes. -#pragma pack(push) -#pragma pack(1) - struct BoneTrafo { - Matrix rotation; // Rotation offset from bone? - Vector trans; // Translation - float scale; // Probably scale (always 1) + Ogre::Matrix3 rotation; // Rotation offset from bone? + Ogre::Vector3 trans; // Translation + float scale; // Probably scale (always 1) }; struct BoneTrafoCopy { @@ -384,12 +377,12 @@ public: short vertex; float weight; }; -#pragma pack(pop) + struct BoneInfo { BoneTrafo trafo; - Vector4 unknown; + Ogre::Vector4 unknown; std::vector weights; }; struct BoneInfoCopy @@ -397,7 +390,7 @@ public: std::string bonename; unsigned short bonehandle; BoneTrafoCopy trafo; - Vector4 unknown; + Ogre::Vector4 unknown; //std::vector weights; }; struct IndividualWeight @@ -411,9 +404,6 @@ public: void read(NIFFile *nif) { - assert(sizeof(BoneTrafo) == 4*(9+3+1)); - assert(sizeof(VertWeight) == 6); - trafo.rotation = nif->getMatrix(); trafo.trans = nif->getVector(); trafo.scale = nif->getFloat(); @@ -432,8 +422,12 @@ public: bi.unknown = nif->getVector4(); // Number of vertex weights - int count = nif->getShort(); - bi.weights = nif->getArrayLen(count); + bi.weights.resize(nif->getShort()); + for(size_t j = 0;j < bi.weights.size();j++) + { + nif->load(bi.weights[j].vertex); + nif->load(bi.weights[j].weight); + } } } }; diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index f48049ec45..30877b48cb 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -38,9 +38,9 @@ struct NiLight : Effect struct SLight { float dimmer; - Vector ambient; - Vector diffuse; - Vector specular; + Ogre::Vector3 ambient; + Ogre::Vector3 diffuse; + Ogre::Vector3 specular; void read(NIFFile *nif) { diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index c4b1382324..d9fdd97aee 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -26,6 +26,9 @@ #include #include +#include +#include +#include #include #include @@ -162,44 +165,31 @@ public: template - std::vector getArrayLen(size_t num) - { - std::vector v(num); - if(inp->read(&v[0], num*sizeof(X)) != num*sizeof(X)) - fail("Failed to read from NIF"); - return v; - } - - template - std::vector getArray() - { - size_t len = read_le32(); - return getArrayLen(len); - } + std::vector getArrayLen(size_t num); char getByte() { char c; return load(c); } unsigned short getShort() { unsigned short s; return load(s); } int getInt() { int i; return load(i); } float getFloat() { float f; return load(f); } - Vector getVector() + Ogre::Vector3 getVector() { - Vector v; - load(v.array); - return v; + float a[3]; + load(a); + return Ogre::Vector3(a); } - Vector4 getVector4() + Ogre::Vector4 getVector4() { - Vector4 v; - load(v.array); - return v; + float a[4]; + load(a); + return Ogre::Vector4(a); } - Matrix getMatrix() + Ogre::Matrix3 getMatrix() { - Matrix m; - m.v[0] = getVector(); - m.v[1] = getVector(); - m.v[2] = getVector(); - return m; + float a[3*3]; + load(a); + return Ogre::Matrix3(Ogre::Real(a[0]), Ogre::Real(a[1]), Ogre::Real(a[2]), + Ogre::Real(a[3]), Ogre::Real(a[4]), Ogre::Real(a[5]), + Ogre::Real(a[6]), Ogre::Real(a[7]), Ogre::Real(a[8])); } Transformation getTrafo() { @@ -228,6 +218,15 @@ public: } }; +template<> +inline std::vector NIFFile::getArrayLen(size_t num) +{ + std::vector v(num); + for(size_t i = 0;i < num;i++) + load(v[i]); + return v; +} + template<> inline std::vector NIFFile::getArrayLen(size_t num) { diff --git a/components/nif/nif_types.hpp b/components/nif/nif_types.hpp index 41900a14ed..705ed5994f 100644 --- a/components/nif/nif_types.hpp +++ b/components/nif/nif_types.hpp @@ -24,41 +24,20 @@ #ifndef _NIF_TYPES_H_ #define _NIF_TYPES_H_ +#include +#include + // Common types used in NIF files namespace Nif { -/* These packing #pragmas aren't really necessary on 32 bit - machines. I haven't tested on 64 bit yet. In any case it doesn't - hurt to include them. We can't allow any compiler-generated padding - in any of these structs, since they are used to interface directly - with raw data from the NIF files. -*/ -#pragma pack(push) -#pragma pack(1) - -struct Vector -{ - float array[3]; -}; - -struct Vector4 -{ - float array[4]; -}; - -struct Matrix -{ - Vector v[3]; -}; - struct Transformation { - Vector pos; - Matrix rotation; + Ogre::Vector3 pos; + Ogre::Matrix3 rotation; float scale; - Vector velocity; + Ogre::Vector3 velocity; static const Transformation& getIdentity() { @@ -67,16 +46,15 @@ struct Transformation if (!iset) { identity.scale = 1.0f; - identity.rotation.v[0].array[0] = 1.0f; - identity.rotation.v[1].array[1] = 1.0f; - identity.rotation.v[2].array[2] = 1.0f; + identity.rotation[0][0] = 1.0f; + identity.rotation[1][1] = 1.0f; + identity.rotation[2][2] = 1.0f; iset = true; } return identity; } }; -#pragma pack(pop) } // Namespace #endif diff --git a/components/nif/node.hpp b/components/nif/node.hpp index d5cd8fe824..6ba3ce61dd 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -47,9 +47,9 @@ public: // Bounding box info bool hasBounds; - Vector boundPos; - Matrix boundRot; - Vector boundXYZ; // Box size + Ogre::Vector3 boundPos; + Ogre::Matrix3 boundRot; + Ogre::Vector3 boundXYZ; // Box size void read(NIFFile *nif) { diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 87e3ae5f23..6ec277a62b 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -167,7 +167,7 @@ struct StructPropT : Property struct S_MaterialProperty { // The vector components are R,G,B - Vector ambient, diffuse, specular, emissive; + Ogre::Vector3 ambient, diffuse, specular, emissive; float glossiness, alpha; void read(NIFFile *nif) diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index ae9ac94c26..41bc3b0a0d 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -43,10 +43,6 @@ http://www.gnu.org/licenses/ . typedef unsigned char ubyte; -using namespace std; -using namespace Ogre; -using namespace Nif; - using namespace NifBullet; ManualBulletShapeLoader::~ManualBulletShapeLoader() @@ -55,18 +51,14 @@ ManualBulletShapeLoader::~ManualBulletShapeLoader() Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr) { - Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2], - tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2], - tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]); - return rot; + return tr->rotation; } Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr) { - Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]); - return vect3; + return tr->pos; } -btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m) +btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m) { Ogre::Quaternion oquat(m); btQuaternion quat; @@ -77,10 +69,9 @@ btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m) return quat; } -btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v) +btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v) { - btVector3 a(v.array[0],v.array[1],v.array[2]); - return a; + return btVector3(v[0], v[1], v[2]); } void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) @@ -108,7 +99,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) assert(r != NULL); Nif::Node *node = dynamic_cast(r); - if (node == NULL) { warn("First record in file was not a node, but a " + diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 5a33074c9e..bf288e0811 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -46,8 +46,6 @@ namespace Nif class Node; class Transformation; class NiTriShape; - class Vector; - class Matrix; } namespace NifBullet @@ -91,9 +89,9 @@ private: Ogre::Vector3 getVector(Nif::Transformation* tr); - btQuaternion getbtQuat(Ogre::Matrix3 m); + btQuaternion getbtQuat(Ogre::Matrix3 &m); - btVector3 getbtVector(Nif::Vector v); + btVector3 getbtVector(Ogre::Vector3 &v); /** *Parse a node. diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index ec54319c18..ad604c8d4a 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -39,9 +39,7 @@ typedef unsigned char ubyte; using namespace std; -using namespace Ogre; using namespace Nif; -using namespace Mangle::VFS; using namespace Misc; using namespace NifOgre; @@ -67,21 +65,6 @@ void NIFLoader::fail(string msg) assert(1); } -Vector3 NIFLoader::convertVector3(const Nif::Vector& vec) -{ - return Ogre::Vector3(vec.array); -} - -Quaternion NIFLoader::convertRotation(const Nif::Matrix& rot) -{ - Real matrix[3][3]; - - for (int i=0; i<3; i++) - for (int j=0; j<3; j++) - matrix[i][j] = rot.v[i].array[j]; - - return Quaternion(Matrix3(matrix)); -} // Helper class that computes the bounding box and of a mesh class BoundsFinder @@ -217,16 +200,16 @@ void NIFLoader::setOutputAnimFiles(bool output){ void NIFLoader::setVerbosePath(std::string path){ verbosePath = path; } -void NIFLoader::createMaterial(const String &name, - const Vector &ambient, - const Vector &diffuse, - const Vector &specular, - const Vector &emissive, +void NIFLoader::createMaterial(const Ogre::String &name, + const Ogre::Vector3 &ambient, + const Ogre::Vector3 &diffuse, + const Ogre::Vector3 &specular, + const Ogre::Vector3 &emissive, float glossiness, float alpha, int alphaFlags, float alphaTest, - const String &texName) + const Ogre::String &texName) { - MaterialPtr material = MaterialManager::getSingleton().create(name, resourceGroup); + Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(name, resourceGroup); //Hardware Skinning code, textures may be the wrong color if enabled @@ -249,11 +232,11 @@ void NIFLoader::createMaterial(const String &name, if (!texName.empty()) { - Pass *pass = material->getTechnique(0)->getPass(0); + Ogre::Pass *pass = material->getTechnique(0)->getPass(0); /*TextureUnitState *txt =*/ pass->createTextureUnitState(texName); - pass->setVertexColourTracking(TVC_DIFFUSE); + pass->setVertexColourTracking(Ogre::TVC_DIFFUSE); // As of yet UNTESTED code from Chris: /*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC); @@ -294,13 +277,13 @@ void NIFLoader::createMaterial(const String &name, NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName); if (result.first) { - pass->setAlphaRejectFunction(CMPF_GREATER_EQUAL); + pass->setAlphaRejectFunction(Ogre::CMPF_GREATER_EQUAL); pass->setAlphaRejectValue(result.second); } else { // Enable transparency - pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); + pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); //pass->setDepthCheckEnabled(false); pass->setDepthWriteEnabled(false); @@ -322,11 +305,11 @@ void NIFLoader::createMaterial(const String &name, const int numsplits = 3; for (int i = 0; i < (split ? numsplits : 1); ++i) { - TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState(); - tu->setName("shadowMap" + StringConverter::toString(i)); - tu->setContentType(TextureUnitState::CONTENT_SHADOW); - tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - tu->setTextureBorderColour(ColourValue::White); + Ogre::TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState(); + tu->setName("shadowMap" + Ogre::StringConverter::toString(i)); + tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW); + tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER); + tu->setTextureBorderColour(Ogre::ColourValue::White); } } @@ -339,11 +322,11 @@ void NIFLoader::createMaterial(const String &name, } // Create a fallback technique without shadows and without mrt - Technique* tech2 = material->createTechnique(); + Ogre::Technique* tech2 = material->createTechnique(); tech2->setSchemeName("Fallback"); - Pass* pass2 = tech2->createPass(); + Ogre::Pass* pass2 = tech2->createPass(); pass2->createTextureUnitState(texName); - pass2->setVertexColourTracking(TVC_DIFFUSE); + pass2->setVertexColourTracking(Ogre::TVC_DIFFUSE); if (Settings::Manager::getBool("shaders", "Objects")) { pass2->setVertexProgram("main_fallback_vp"); @@ -352,16 +335,16 @@ void NIFLoader::createMaterial(const String &name, } // Add material bells and whistles - material->setAmbient(ambient.array[0], ambient.array[1], ambient.array[2]); - material->setDiffuse(diffuse.array[0], diffuse.array[1], diffuse.array[2], alpha); - material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha); - material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); + material->setAmbient(ambient[0], ambient[1], ambient[2]); + material->setDiffuse(diffuse[0], diffuse[1], diffuse[2], alpha); + material->setSpecular(specular[0], specular[1], specular[2], alpha); + material->setSelfIllumination(emissive[0], emissive[1], emissive[2]); material->setShininess(glossiness); } // Takes a name and adds a unique part to it. This is just used to // make sure that all materials are given unique names. -String NIFLoader::getUniqueName(const String &input) +Ogre::String NIFLoader::getUniqueName(const Ogre::String &input) { static int addon = 0; static char buf[8]; @@ -377,13 +360,13 @@ String NIFLoader::getUniqueName(const String &input) // does not, change the string IN PLACE to say .dds instead and try // that. The texture may still not exist, but no information of value // is lost in that case. -void NIFLoader::findRealTexture(String &texName) +void NIFLoader::findRealTexture(Ogre::String &texName) { if(Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName)) return; // Change texture extension to .dds - String::size_type pos = texName.rfind('.'); + Ogre::String::size_type pos = texName.rfind('.'); texName.replace(pos, texName.length(), ".dds"); } @@ -391,11 +374,11 @@ void NIFLoader::findRealTexture(String &texName) // Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. -void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list &vertexBoneAssignments) +void NIFLoader::createOgreSubMesh(NiTriShape *shape, const Ogre::String &material, std::list &vertexBoneAssignments) { // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); - SubMesh *sub = mesh->createSubMesh(shape->name); + Ogre::SubMesh *sub = mesh->createSubMesh(shape->name); int nextBuf = 0; @@ -404,17 +387,17 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std // Add vertices int numVerts = data->vertices.size() / 3; - sub->vertexData = new VertexData(); + sub->vertexData = new Ogre::VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; - VertexDeclaration *decl = sub->vertexData->vertexDeclaration; - decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); + Ogre::VertexDeclaration *decl = sub->vertexData->vertexDeclaration; + decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3), - numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false); + Ogre::HardwareVertexBufferSharedPtr vbuf = + Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), + numVerts, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false); if(flip) { @@ -440,19 +423,19 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std } - VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; + Ogre::VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); if (data->normals.size()) { - decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); - vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3), - numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); + vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), + numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); if(flip) { - Quaternion rotation = mTransform.extractQuaternion(); + Ogre::Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); float *datamod = new float[data->normals.size()]; @@ -487,19 +470,19 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std if (data->colors.size()) { const float *colors = &data->colors[0]; - RenderSystem* rs = Root::getSingleton().getRenderSystem(); - std::vector colorsRGB(numVerts); - RGBA *pColour = &colorsRGB.front(); + Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); + std::vector colorsRGB(numVerts); + Ogre::RGBA *pColour = &colorsRGB.front(); for (int i=0; iconvertColourValue(ColourValue(colors[0],colors[1],colors[2], - colors[3]),pColour++); + rs->convertColourValue(Ogre::ColourValue(colors[0],colors[1],colors[2], + colors[3]),pColour++); colors += 4; } - decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); - vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_COLOUR), - numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); + vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR), + numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); bind->setBinding(nextBuf++, vbuf); } @@ -507,10 +490,10 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std if (data->uvlist.size()) { - decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); - vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT2), - numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); + decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); + vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2), + numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); if(flip) { @@ -539,24 +522,23 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std sub->indexData->indexCount = numFaces; sub->indexData->indexStart = 0; - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_16BIT, - numFaces, - HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); + Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton(). + createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, numFaces, + Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){ sub->indexData->indexBuffer = ibuf; - uint16 *datamod = new uint16[numFaces]; + uint16_t *datamod = new uint16_t[numFaces]; int index = 0; for (size_t i = 0; i < sub->indexData->indexCount; i+=3) { const short *pos = &data->triangles[index]; - uint16 i0 = (uint16) *(pos+0); - uint16 i1 = (uint16) *(pos+1); - uint16 i2 = (uint16) *(pos+2); + uint16_t i0 = (uint16_t) *(pos+0); + uint16_t i1 = (uint16_t) *(pos+1); + uint16_t i2 = (uint16_t) *(pos+2); //std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n"; @@ -582,7 +564,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std //add vertex bone assignments - for (std::list::iterator it = vertexBoneAssignments.begin(); + for (std::list::iterator it = vertexBoneAssignments.begin(); it != vertexBoneAssignments.end(); it++) { sub->addBoneAssignment(*it); @@ -593,23 +575,8 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std // 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) +static void vectorMulAdd(const Ogre::Matrix3 &A, const Ogre::Vector3 &B, float *C, float scale) { // Keep the original values float a = C[0]; @@ -618,11 +585,11 @@ static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale // 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; + C[i] = B[i] + (a*A[i][0] + b*A[i][1] + c*A[i][2])*scale; } // Computes B = AxB (matrix*vector) -static void vectorMul(const Matrix &A, float *C) +static void vectorMul(const Ogre::Matrix3 &A, float *C) { // Keep the original values float a = C[0]; @@ -631,7 +598,7 @@ static void vectorMul(const Matrix &A, float *C) // 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]; + C[i] = a*A[i][0] + b*A[i][1] + c*A[i][2]; } @@ -666,7 +633,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou return; // Material name for this submesh, if any - String material; + Ogre::String material; // Skip the entire material phase for hidden nodes if (!hidden) @@ -695,7 +662,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou } // Texture - String texName; + Ogre::String texName; if (t && t->textures[0].inUse) { NiSourceTexture *st = t->textures[0].texture.getPtr(); @@ -768,14 +735,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou { // We only have a texture name. Create a default // material for it. - Vector zero, one; - for (int i=0; i<3;i++) - { - zero.array[i] = 0.0; - one.array[i] = 1.0; - } - - createMaterial(material, one, one, zero, zero, 0.0, 1.0, + const Ogre::Vector3 zero(0.0f), one(1.0f); + createMaterial(material, one, one, zero, zero, 0.0f, 1.0f, alphaFlags, alphaTest, texName); } } @@ -793,7 +754,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou float *ptr = (float*)&data->vertices[0]; float *optr = ptr; - std::list vertexBoneAssignments; + std::list vertexBoneAssignments; Nif::NiTriShapeCopy copy = shape->clone(); @@ -826,9 +787,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou //the first one contains a link to the bone, the second vertex transformation //relative to the bone int boneIndex = 0; - Bone *bonePtr; - Vector3 vecPos; - Quaternion vecRot; + Ogre::Bone *bonePtr; + Ogre::Vector3 vecPos; + Ogre::Quaternion vecRot; std::vector boneList = shape->skin->data->bones; @@ -854,17 +815,17 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou Nif::NiSkinData::BoneInfoCopy boneinfocopy; - boneinfocopy.trafo.rotation = convertRotation(it->trafo.rotation); - boneinfocopy.trafo.trans = convertVector3(it->trafo.trans); + boneinfocopy.trafo.rotation = it->trafo.rotation; + boneinfocopy.trafo.trans = it->trafo.trans; boneinfocopy.bonename = shape->skin->bones[boneIndex].name; boneinfocopy.bonehandle = bonePtr->getHandle(); copy.boneinfo.push_back(boneinfocopy); for (unsigned int i=0; iweights.size(); i++) { vecPos = bonePtr->_getDerivedPosition() + - bonePtr->_getDerivedOrientation() * convertVector3(it->trafo.trans); + bonePtr->_getDerivedOrientation() * it->trafo.trans; - vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo.rotation); + vecRot = bonePtr->_getDerivedOrientation() * it->trafo.rotation; unsigned int verIndex = it->weights[i].vertex; //boneinfo.weights.push_back(*(it->weights.ptr + i)); Nif::NiSkinData::IndividualWeight ind; @@ -885,9 +846,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou if (vertexPosAbsolut[verIndex] == false) { //apply transformation to the vertices - Vector3 absVertPos = vecPos + vecRot * Vector3(ptr + verIndex *3); + Ogre::Vector3 absVertPos = vecPos + vecRot * Ogre::Vector3(ptr + verIndex *3); absVertPos = absVertPos * it->weights[i].weight; - vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3); + vertexPosOriginal[verIndex] = Ogre::Vector3(ptr + verIndex *3); mBoundingBox.merge(absVertPos); //convert it back to float * @@ -898,9 +859,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou //FIXME: I guessed that vertex[i] = normal[i], is that true? if (verIndex < data->normals.size()) { - Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3); + Ogre::Vector3 absNormalsPos = vecRot * Ogre::Vector3(ptrNormals + verIndex *3); absNormalsPos = absNormalsPos * it->weights[i].weight; - vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3); + vertexNormalOriginal[verIndex] = Ogre::Vector3(ptrNormals + verIndex *3); for (int j=0; j<3; j++) (ptrNormals + verIndex*3)[j] = absNormalsPos[j]; @@ -910,9 +871,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou } else { - Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex]; + Ogre::Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex]; absVertPos = absVertPos * it->weights[i].weight; - Vector3 old = Vector3(ptr + verIndex *3); + Ogre::Vector3 old = Ogre::Vector3(ptr + verIndex *3); absVertPos = absVertPos + old; mBoundingBox.merge(absVertPos); @@ -924,9 +885,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou //FIXME: I guessed that vertex[i] = normal[i], is that true? if (verIndex < data->normals.size()) { - Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex]; + Ogre::Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex]; absNormalsPos = absNormalsPos * it->weights[i].weight; - Vector3 oldNormal = Vector3(ptrNormals + verIndex *3); + Ogre::Vector3 oldNormal = Ogre::Vector3(ptrNormals + verIndex *3); absNormalsPos = absNormalsPos + oldNormal; for (int j=0; j<3; j++) @@ -935,7 +896,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou } - VertexBoneAssignment vba; + Ogre::VertexBoneAssignment vba; vba.boneIndex = bonePtr->getHandle(); vba.vertexIndex = verIndex; vba.weight = it->weights[i].weight; @@ -955,12 +916,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou copy.boneSequence = boneSequence; // Rotate, scale and translate all the vertices, - const Matrix &rot = shape->trafo.rotation; - const Vector &pos = shape->trafo.pos; + const Ogre::Matrix3 &rot = shape->trafo.rotation; + const Ogre::Vector3 &pos = shape->trafo.pos; float scale = shape->trafo.scale; - copy.trafo.trans = convertVector3(original.pos); - copy.trafo.rotation = convertRotation(original.rotation); + copy.trafo.trans = original.pos; + copy.trafo.rotation = original.rotation; copy.trafo.scale = original.scale; //We don't use velocity for anything yet, so it does not need to be saved @@ -988,7 +949,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou boneIndex = mSkel->getNumBones() - 1; for(int i = 0; i < numVerts; i++){ - VertexBoneAssignment vba; + Ogre::VertexBoneAssignment vba; vba.boneIndex = boneIndex; vba.vertexIndex = i; vba.weight = 1; @@ -1012,15 +973,15 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou void NIFLoader::calculateTransform() { // Calculate transform - Matrix4 transform = Matrix4::IDENTITY; - transform = Matrix4::getScale(vector) * transform; + Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY; + transform = Ogre::Matrix4::getScale(vector) * transform; // Check whether we have to flip vertex winding. // We do have to, if we changed our right hand base. // We can test it by using the cross product from X and Y and see, if it is a non-negative // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // but the test is cheap either way. - Matrix3 m3; + Ogre::Matrix3 m3; transform.extract3x3Matrix(m3); if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) @@ -1114,7 +1075,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, } } - Bone *bone = 0; + Ogre::Bone *bone = 0; // create skeleton or add bones if (node->recType == RC_NiNode) @@ -1124,7 +1085,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, { inTheSkeletonTree = true; - mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); + mSkel = Ogre::SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); } else if (!mSkel.isNull() && !parentBone) inTheSkeletonTree = false; @@ -1144,8 +1105,8 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, parentBone->addChild(bone); bone->setInheritOrientation(true); - bone->setPosition(convertVector3(node->trafo.pos)); - bone->setOrientation(convertRotation(node->trafo.rotation)); + bone->setPosition(node->trafo.pos); + bone->setOrientation(node->trafo.rotation); } } } @@ -1160,14 +1121,13 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, // 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); + final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale; + final.velocity = trafo->velocity + trafo->rotation*final.velocity*trafo->scale; // Merge the rotations together - matrixMul(trafo->rotation, final.rotation); + final.rotation = trafo->rotation * final.rotation; - // Scalar values are so nice to deal with. Why can't everything - // just be scalar? + // Scale final.scale *= trafo->scale; } @@ -1200,7 +1160,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, } } -void NIFLoader::loadResource(Resource *resource) +void NIFLoader::loadResource(Ogre::Resource *resource) { inTheSkeletonTree = false; allanim.clear(); @@ -1287,7 +1247,7 @@ void NIFLoader::loadResource(Resource *resource) calculateTransform(); } // Get the mesh - mesh = dynamic_cast(resource); + mesh = dynamic_cast(resource); assert(mesh); // Look it up @@ -1352,8 +1312,8 @@ void NIFLoader::loadResource(Resource *resource) // set the bounding value. if (bounds.isValid()) { - mesh->_setBounds(AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(), - bounds.maxX(), bounds.maxY(), bounds.maxZ())); + mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(), + bounds.maxX(), bounds.maxY(), bounds.maxZ())); mesh->_setBoundingSphereRadius(bounds.getRadius()); } if(hasAnim && addAnim){ @@ -1375,7 +1335,7 @@ void NIFLoader::loadResource(Resource *resource) for(std::vector::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++) { int boneIndex = mSkel->getNumBones() - 1; - VertexBoneAssignment vba; + Ogre::VertexBoneAssignment vba; vba.boneIndex = boneIndex; vba.vertexIndex = 0; vba.weight = 1; @@ -1394,20 +1354,19 @@ void NIFLoader::loadResource(Resource *resource) -MeshPtr NIFLoader::load(const std::string &name, - const std::string &group) +Ogre::MeshPtr NIFLoader::load(const std::string &name, const std::string &group) { - MeshManager *m = MeshManager::getSingletonPtr(); + Ogre::MeshManager *m = Ogre::MeshManager::getSingletonPtr(); // Check if the resource already exists - ResourcePtr ptr = m->getByName(name, group); - MeshPtr themesh; + Ogre::ResourcePtr ptr = m->getByName(name, group); + Ogre::MeshPtr themesh; if (!ptr.isNull()){ - themesh = MeshPtr(ptr); + themesh = Ogre::MeshPtr(ptr); } else // Nope, create a new one. { - themesh = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); + themesh = Ogre::MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); } return themesh; } diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 55915b3102..64efc70c7d 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -62,17 +62,8 @@ namespace Nif class Node; class Transformation; class NiTriShape; - class Vector; - class Matrix; } -namespace Mangle -{ - namespace VFS - { - class OgreVFS; - } -} namespace NifOgre { @@ -110,9 +101,6 @@ class NIFLoader : Ogre::ManualResourceLoader std::map* getTextIndices(std::string name); - Ogre::Vector3 convertVector3(const Nif::Vector& vec); - Ogre::Quaternion convertRotation(const Nif::Matrix& rot); - void setOutputAnimFiles(bool output); void setVerbosePath(std::string path); @@ -136,10 +124,10 @@ class NIFLoader : Ogre::ManualResourceLoader void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list &vertexBoneAssignments); void createMaterial(const Ogre::String &name, - const Nif::Vector &ambient, - const Nif::Vector &diffuse, - const Nif::Vector &specular, - const Nif::Vector &emissive, + const Ogre::Vector3 &ambient, + const Ogre::Vector3 &diffuse, + const Ogre::Vector3 &specular, + const Ogre::Vector3 &emissive, float glossiness, float alpha, int alphaFlags, float alphaTest, const Ogre::String &texName); From 70c74ede055b2bbfcb727dcc9c8e92f082cd9554 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 10 Jul 2012 11:53:12 +0200 Subject: [PATCH 40/51] changed rotation order --- apps/openmw/mwworld/worldimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1e1fae1548..24baac1442 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -618,7 +618,7 @@ namespace MWWorld Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X); Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); - ptr.getRefData().getBaseNode()->setOrientation(rotz*rotx*roty); + ptr.getRefData().getBaseNode()->setOrientation(rotz*roty*rotx); mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); } From 95b804a104ef4c187a53f3b8228932278ef4f752 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 03:02:37 -0700 Subject: [PATCH 41/51] Remove NIFFile::getArrayLen --- components/nif/data.hpp | 17 ++++++++--------- components/nif/extra.hpp | 11 ++++++++--- components/nif/nif_file.cpp | 2 +- components/nif/nif_file.hpp | 34 ++-------------------------------- 4 files changed, 19 insertions(+), 45 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 667e77ffd5..babc07545d 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -105,25 +105,24 @@ public: int verts = nif->getShort(); if(nif->getInt()) - vertices = nif->getArrayLen(verts*3); + nif->load(vertices, verts*3); if(nif->getInt()) - normals = nif->getArrayLen(verts*3); + nif->load(normals, verts*3); center = nif->getVector(); radius = nif->getFloat(); if(nif->getInt()) - colors = nif->getArrayLen(verts*4); - - int uvs = nif->getShort(); + nif->load(colors, verts*4); // Only the first 6 bits are used as a count. I think the rest are // flags of some sort. + int uvs = nif->getShort(); uvs &= 0x3f; if(nif->getInt()) - uvlist = nif->getArrayLen(uvs*verts*2); + nif->load(uvlist, uvs*verts*2); } }; @@ -143,7 +142,7 @@ public: // We have three times as many vertices as triangles, so this // is always equal to tris*3. int cnt = nif->getInt(); - triangles = nif->getArrayLen(cnt); + nif->load(triangles, cnt); } // Read the match list, which lists the vertices that are equal to @@ -175,13 +174,13 @@ public: activeCount = nif->getShort(); // Skip all the info, we don't support particles yet - nif->getFloat(); // Active radius ? + nif->getFloat(); // Active radius ? nif->getShort(); // Number of valid entries in the following arrays ? if(nif->getInt()) { // Particle sizes - nif->getArrayLen(activeCount); + nif->skip(activeCount * sizeof(float)); } } }; diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 5615d833ef..7659bb3d27 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -47,16 +47,21 @@ public: class NiVertWeightsExtraData : public Extra { public: + std::vector weights; + void read(NIFFile *nif) { Extra::read(nif); + int i; + unsigned short s; + // We should have s*4+2 == i, for some reason. Might simply be the // size of the rest of the record, unhelpful as that may be. - /*int i =*/ nif->getInt(); - int s = nif->getShort(); // number of vertices + nif->load(i); - nif->getArrayLen(s); // vertex weights I guess + nif->load(s); // number of vertices + nif->load(weights, s); // vertex weights I guess } }; diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 36badbf0d8..5b88b45fec 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -46,7 +46,7 @@ using namespace Misc; void NIFFile::parse() { // Check the header string - std::string head = getString(40); + std::string head = read_string(40); if(head.compare(0, 22, "NetImmerse File Format") != 0) fail("Invalid NIF header"); diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index d9fdd97aee..6165f58118 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -164,9 +164,6 @@ public: } - template - std::vector getArrayLen(size_t num); - char getByte() { char c; return load(c); } unsigned short getShort() { unsigned short s; return load(s); } int getInt() { int i; return load(i); } @@ -202,39 +199,12 @@ public: } - // For fixed-size strings where you already know the size - std::string getString(size_t size) - { - std::string str; - str.resize(size); - if(inp->read(&str[0], size) != size) - fail("Failed to read from NIF"); - return str.substr(0, str.find('\0')); - } std::string getString() { - size_t size = getInt(); - return getString(size); + size_t size = read_le32(); + return read_string(size); } }; -template<> -inline std::vector NIFFile::getArrayLen(size_t num) -{ - std::vector v(num); - for(size_t i = 0;i < num;i++) - load(v[i]); - return v; -} - -template<> -inline std::vector NIFFile::getArrayLen(size_t num) -{ - std::vector v(num); - for(size_t i = 0;i < num;i++) - load(v[i]); - return v; -} - } // Namespace #endif From 164a5c8fe4d6ab0abda8116f872f90eaac6ce960 Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 10 Jul 2012 12:10:50 +0200 Subject: [PATCH 42/51] rotation now also work with the physic representation --- apps/openmw/mwworld/physicssystem.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 9848efe6eb..7d7b237aec 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -291,12 +291,14 @@ namespace MWWorld void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) { - if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); } + if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) + { + body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); + } } void PhysicsSystem::scaleObject (const std::string& handle, float scale) From 930459365b1ca8842acd1d36299bf8820e43242f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 03:52:01 -0700 Subject: [PATCH 43/51] Rename getShort->getUShort and getByte->getChar --- components/nif/controller.hpp | 8 +++---- components/nif/data.hpp | 39 ++++++++++++++++------------------- components/nif/nif_file.hpp | 6 +++--- components/nif/node.hpp | 2 +- components/nif/property.hpp | 12 +++++------ 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index d00c1bc0ef..cbc19cd8f5 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -44,7 +44,7 @@ public: { next.read(nif); - flags = nif->getShort(); + flags = nif->getUShort(); frequency = nif->getFloat(); phase = nif->getFloat(); @@ -71,7 +71,7 @@ public: // At the moment, just skip it all nif->skip(111); - int s = nif->getShort(); + int s = nif->getUShort(); nif->skip(15 + s*40); } }; @@ -133,7 +133,7 @@ public: { Controller::read(nif); - nif->getShort(); // always 0 + nif->getUShort(); // always 0 data.read(nif); } @@ -189,7 +189,7 @@ public: { Controller::read(nif); data.read(nif); - nif->getByte(); // always 0 + nif->getChar(); // always 0 } void post(NIFFile *nif) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index babc07545d..e77fd62390 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -69,12 +69,12 @@ public: { Named::read(nif); - external = !!nif->getByte(); + external = !!nif->getChar(); if(external) filename = nif->getString(); else { - nif->getByte(); // always 1 + nif->getChar(); // always 1 data.read(nif); } @@ -82,7 +82,7 @@ public: mipmap = nif->getInt(); alpha = nif->getInt(); - nif->getByte(); // always 1 + nif->getChar(); // always 1 } void post(NIFFile *nif) @@ -102,7 +102,7 @@ public: void read(NIFFile *nif) { - int verts = nif->getShort(); + int verts = nif->getUShort(); if(nif->getInt()) nif->load(vertices, verts*3); @@ -118,7 +118,7 @@ public: // Only the first 6 bits are used as a count. I think the rest are // flags of some sort. - int uvs = nif->getShort(); + int uvs = nif->getUShort(); uvs &= 0x3f; if(nif->getInt()) @@ -136,7 +136,7 @@ public: { ShapeData::read(nif); - int tris = nif->getShort(); + int tris = nif->getUShort(); if(tris) { // We have three times as many vertices as triangles, so this @@ -148,15 +148,12 @@ public: // Read the match list, which lists the vertices that are equal to // vertices. We don't actually need need this for anything, so // just skip it. - int verts = nif->getShort(); - if(verts) + int verts = nif->getUShort(); + for(int i=0;igetShort(); - nif->skip(num*sizeof(short)); - } + // Number of vertices matching vertex 'i' + int num = nif->getUShort(); + nif->skip(num*sizeof(short)); } } }; @@ -171,11 +168,11 @@ public: ShapeData::read(nif); // Should always match the number of vertices - activeCount = nif->getShort(); + activeCount = nif->getUShort(); // Skip all the info, we don't support particles yet - nif->getFloat(); // Active radius ? - nif->getShort(); // Number of valid entries in the following arrays ? + nif->getFloat(); // Active radius ? + nif->getUShort(); // Number of valid entries in the following arrays ? if(nif->getInt()) { @@ -421,11 +418,11 @@ public: bi.unknown = nif->getVector4(); // Number of vertex weights - bi.weights.resize(nif->getShort()); + bi.weights.resize(nif->getUShort()); for(size_t j = 0;j < bi.weights.size();j++) { - nif->load(bi.weights[j].vertex); - nif->load(bi.weights[j].weight); + bi.weights[j].vertex = nif->getUShort(); + bi.weights[j].weight = nif->getFloat(); } } } @@ -464,7 +461,7 @@ public: { int morphCount = nif->getInt(); int vertCount = nif->getInt(); - nif->getByte(); + nif->getChar(); int magic = nif->getInt(); /*int type =*/ nif->getInt(); diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 6165f58118..2b46f84f3a 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -164,8 +164,8 @@ public: } - char getByte() { char c; return load(c); } - unsigned short getShort() { unsigned short s; return load(s); } + char getChar() { char c; return load(c); } + unsigned short getUShort() { unsigned short s; return load(s); } int getInt() { int i; return load(i); } float getFloat() { float f; return load(f); } Ogre::Vector3 getVector() @@ -193,7 +193,7 @@ public: Transformation t; t.pos = getVector(); t.rotation = getMatrix(); - load(t.scale); + t.scale = getFloat(); t.velocity = getVector(); return t; } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 6ba3ce61dd..f86ea5af92 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -55,7 +55,7 @@ public: { Named::read(nif); - flags = nif->getShort(); + flags = nif->getUShort(); trafo = nif->getTrafo(); props.read(nif); diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 6ec277a62b..1b455b14f3 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -38,7 +38,7 @@ public: void read(NIFFile *nif) { Named::read(nif); - flags = nif->getShort(); + flags = nif->getUShort(); } }; @@ -176,8 +176,8 @@ struct S_MaterialProperty diffuse = nif->getVector(); specular = nif->getVector(); emissive = nif->getVector(); - nif->load(glossiness); - nif->load(alpha); + glossiness = nif->getFloat(); + alpha = nif->getFloat(); } }; @@ -196,8 +196,8 @@ struct S_VertexColorProperty void read(NIFFile *nif) { - nif->load(vertmode); - nif->load(lightmode); + vertmode = nif->getInt(); + lightmode = nif->getInt(); } }; @@ -253,7 +253,7 @@ struct S_AlphaProperty void read(NIFFile *nif) { - nif->load(threshold); + threshold = nif->getChar(); } }; From d30f64650a323f84d7ea554b7e0d3e4728cc1b47 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 04:21:47 -0700 Subject: [PATCH 44/51] Make the read_* methods private and remove the generic load() methods --- components/nif/data.hpp | 12 ++-- components/nif/effect.hpp | 2 +- components/nif/extra.hpp | 11 +-- components/nif/nif_file.cpp | 2 +- components/nif/nif_file.hpp | 140 +++++++++++++++++------------------- components/nif/node.hpp | 22 +++--- 6 files changed, 87 insertions(+), 102 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index e77fd62390..118e21e547 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -105,16 +105,16 @@ public: int verts = nif->getUShort(); if(nif->getInt()) - nif->load(vertices, verts*3); + nif->getFloats(vertices, verts*3); if(nif->getInt()) - nif->load(normals, verts*3); + nif->getFloats(normals, verts*3); center = nif->getVector(); radius = nif->getFloat(); if(nif->getInt()) - nif->load(colors, verts*4); + nif->getFloats(colors, verts*4); // Only the first 6 bits are used as a count. I think the rest are // flags of some sort. @@ -122,7 +122,7 @@ public: uvs &= 0x3f; if(nif->getInt()) - nif->load(uvlist, uvs*verts*2); + nif->getFloats(uvlist, uvs*verts*2); } }; @@ -142,7 +142,7 @@ public: // We have three times as many vertices as triangles, so this // is always equal to tris*3. int cnt = nif->getInt(); - nif->load(triangles, cnt); + nif->getShorts(triangles, cnt); } // Read the match list, which lists the vertices that are equal to @@ -153,7 +153,7 @@ public: { // Number of vertices matching vertex 'i' int num = nif->getUShort(); - nif->skip(num*sizeof(short)); + nif->skip(num * sizeof(short)); } } }; diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 30877b48cb..1a2ecace80 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -44,7 +44,7 @@ struct NiLight : Effect void read(NIFFile *nif) { - nif->load(dimmer); + dimmer = nif->getFloat(); ambient = nif->getVector(); diffuse = nif->getVector(); specular = nif->getVector(); diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 7659bb3d27..35781dbf59 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -47,21 +47,16 @@ public: class NiVertWeightsExtraData : public Extra { public: - std::vector weights; - void read(NIFFile *nif) { Extra::read(nif); - int i; - unsigned short s; - // We should have s*4+2 == i, for some reason. Might simply be the // size of the rest of the record, unhelpful as that may be. - nif->load(i); + /*int i =*/ nif->getInt(); + int s = nif->getUShort(); - nif->load(s); // number of vertices - nif->load(weights, s); // vertex weights I guess + nif->skip(s * sizeof(float)); // vertex weights I guess } }; diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 5b88b45fec..36badbf0d8 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -46,7 +46,7 @@ using namespace Misc; void NIFFile::parse() { // Check the header string - std::string head = read_string(40); + std::string head = getString(40); if(head.compare(0, 22, "NetImmerse File Format") != 0) fail("Invalid NIF header"); diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 2b46f84f3a..0218795e01 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -62,6 +62,33 @@ class NIFFile /// Parse the file void parse(); + uint8_t read_byte() + { + uint8_t byte; + if(inp->read(&byte, 1) != 1) return 0; + return byte; + } + uint16_t read_le16() + { + uint8_t buffer[2]; + if(inp->read(buffer, 2) != 2) return 0; + return buffer[0] | (buffer[1]<<8); + } + uint32_t read_le32() + { + uint8_t buffer[4]; + if(inp->read(buffer, 4) != 4) return 0; + return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); + } + float read_le32f() + { + union { + int i; + float f; + } u = { read_le32() }; + return u.f; + } + public: /// Used for error handling void fail(const std::string &msg) @@ -102,91 +129,34 @@ public: void skip(size_t size) { inp->skip(size); } - uint32_t read_le32() - { - uint8_t buffer[4]; - if(inp->read(buffer, 4) != 4) return 0; - return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); - } - uint16_t read_le16() - { - uint8_t buffer[2]; - if(inp->read(buffer, 2) != 2) return 0; - return buffer[0] | (buffer[1]<<8); - } - uint8_t read_byte() - { - uint8_t byte; - if(inp->read(&byte, 1) != 1) return 0; - return byte; - } - std::string read_string(size_t length) - { - std::string str; - str.resize(length); - if(inp->read(&str[0], length) != length) - return std::string(); - return str.substr(0, str.find('\0')); - } - - - char& load(char &c) { c = read_byte(); return c; } - unsigned char& load(unsigned char &c) { c = read_byte(); return c; } - short& load(short &s) { s = read_le16(); return s; } - unsigned short& load(unsigned short &s) { s = read_le16(); return s; } - int& load(int &i) { i = read_le32(); return i; } - unsigned int& load(unsigned int &i) { i = read_le32(); return i; } - float& load(float &f) - { - union { - int i; - float f; - } u = { read_le32() }; - f = u.f; - return f; - } - - template - T* load(T (&a)[N]) - { - for(size_t i = 0;i < N;i++) - load(a[i]); - return a; - } - - template - std::vector& load(std::vector &v, size_t size) - { - v.resize(size); - for(size_t i = 0;i < size;i++) - load(v[i]); - return v; - } - - - char getChar() { char c; return load(c); } - unsigned short getUShort() { unsigned short s; return load(s); } - int getInt() { int i; return load(i); } - float getFloat() { float f; return load(f); } + char getChar() { return read_byte(); } + short getShort() { return read_le16(); } + unsigned short getUShort() { return read_le16(); } + int getInt() { return read_le32(); } + float getFloat() { return read_le32f(); } Ogre::Vector3 getVector() { float a[3]; - load(a); + for(size_t i = 0;i < 3;i++) + a[i] = getFloat(); return Ogre::Vector3(a); } Ogre::Vector4 getVector4() { float a[4]; - load(a); + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); return Ogre::Vector4(a); } Ogre::Matrix3 getMatrix() { - float a[3*3]; - load(a); - return Ogre::Matrix3(Ogre::Real(a[0]), Ogre::Real(a[1]), Ogre::Real(a[2]), - Ogre::Real(a[3]), Ogre::Real(a[4]), Ogre::Real(a[5]), - Ogre::Real(a[6]), Ogre::Real(a[7]), Ogre::Real(a[8])); + Ogre::Real a[3][3]; + for(size_t i = 0;i < 3;i++) + { + for(size_t j = 0;j < 3;j++) + a[i][j] = Ogre::Real(getFloat()); + } + return Ogre::Matrix3(a); } Transformation getTrafo() { @@ -198,11 +168,31 @@ public: return t; } - + std::string getString(size_t length) + { + std::string str; + str.resize(length); + if(inp->read(&str[0], length) != length) + return std::string(); + return str.substr(0, str.find('\0')); + } std::string getString() { size_t size = read_le32(); - return read_string(size); + return getString(size); + } + + void getShorts(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getShort(); + } + void getFloats(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getFloat(); } }; diff --git a/components/nif/node.hpp b/components/nif/node.hpp index f86ea5af92..240dbe540c 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -221,19 +221,19 @@ struct NiCamera : Node void read(NIFFile *nif) { - nif->load(left); - nif->load(right); - nif->load(top); - nif->load(bottom); - nif->load(nearDist); - nif->load(farDist); + left = nif->getFloat(); + right = nif->getFloat(); + top = nif->getFloat(); + bottom = nif->getFloat(); + nearDist = nif->getFloat(); + farDist = nif->getFloat(); - nif->load(vleft); - nif->load(vright); - nif->load(vtop); - nif->load(vbottom); + vleft = nif->getFloat(); + vright = nif->getFloat(); + vtop = nif->getFloat(); + vbottom = nif->getFloat(); - nif->load(LOD); + LOD = nif->getFloat(); } }; Camera cam; From f11bf49a9023cff3ceebdeab6326a5379f878995 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 10 Jul 2012 13:23:41 +0200 Subject: [PATCH 45/51] cmake fix; silenced some warnings --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwworld/physicssystem.cpp | 13 ++++----- components/nifbullet/bullet_nif_loader.cpp | 34 +++++++++++----------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 9534ecc904..b12c58f0d4 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -39,7 +39,7 @@ add_openmw_dir (mwscript locals scriptmanager compilercontext interpretercontext cellextensions miscextensions guiextensions soundextensions skyextensions statsextensions containerextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions - animationextensions + animationextensions transformationextensions ) add_openmw_dir (mwsound diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 7d7b237aec..105995aca7 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -165,7 +165,6 @@ namespace MWWorld for (std::vector >::const_iterator iter (actors.begin()); iter!=actors.end(); ++iter) { - OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first); //dirty stuff to get the camera orientation. Must be changed! Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); @@ -175,10 +174,10 @@ namespace MWWorld Ogre::Quaternion yawQuat = yawNode->getOrientation(); Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); - + playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); - + playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; @@ -194,9 +193,9 @@ namespace MWWorld } - - - + + + mEngine->stepSimulation(dt); } @@ -307,7 +306,7 @@ namespace MWWorld { btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform(); removeObject(handle); - + Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ()); Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()); addObject(handle, handleToMesh[handle], quat, scale, vec); diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 17c5f18aca..f66239e7ba 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -82,17 +82,17 @@ static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float 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]; +//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]; -} +// // 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() @@ -233,7 +233,7 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, 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; @@ -267,11 +267,11 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, } } - - + + 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); @@ -287,9 +287,9 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, // 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) @@ -304,7 +304,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, } } } - else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) + else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) { cShape->collide = true; handleNiTriShape(dynamic_cast(node), flags,getMatrix(node->trafo),getVector(node->trafo),node->trafo->scale,raycastingOnly); From dddf1b4ee57328f47226825a694a0e04d70149f8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Jul 2012 04:45:14 -0700 Subject: [PATCH 46/51] Rename getMatrix->getMatrix3 and getVector->getVector3 --- components/nif/data.hpp | 18 +++++++++--------- components/nif/effect.hpp | 6 +++--- components/nif/nif_file.hpp | 10 +++++----- components/nif/node.hpp | 6 +++--- components/nif/property.hpp | 8 ++++---- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 118e21e547..ad670bc5e6 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -110,7 +110,7 @@ public: if(nif->getInt()) nif->getFloats(normals, verts*3); - center = nif->getVector(); + center = nif->getVector3(); radius = nif->getFloat(); if(nif->getInt()) @@ -214,12 +214,12 @@ public: for(int i=0; igetFloat(); - nif->getVector(); // This isn't really shared between type 1 - // and type 2, most likely + nif->getVector3(); // This isn't really shared between type 1 + // and type 2, most likely if(type == 2) { - nif->getVector(); - nif->getVector(); + nif->getVector3(); + nif->getVector3(); } } } @@ -400,8 +400,8 @@ public: void read(NIFFile *nif) { - trafo.rotation = nif->getMatrix(); - trafo.trans = nif->getVector(); + trafo.rotation = nif->getMatrix3(); + trafo.trans = nif->getVector3(); trafo.scale = nif->getFloat(); int boneNum = nif->getInt(); @@ -412,8 +412,8 @@ public: { BoneInfo &bi = bones[i]; - bi.trafo.rotation = nif->getMatrix(); - bi.trafo.trans = nif->getVector(); + bi.trafo.rotation = nif->getMatrix3(); + bi.trafo.trans = nif->getVector3(); bi.trafo.scale = nif->getFloat(); bi.unknown = nif->getVector4(); diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 1a2ecace80..850415dadc 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -45,9 +45,9 @@ struct NiLight : Effect void read(NIFFile *nif) { dimmer = nif->getFloat(); - ambient = nif->getVector(); - diffuse = nif->getVector(); - specular = nif->getVector(); + ambient = nif->getVector3(); + diffuse = nif->getVector3(); + specular = nif->getVector3(); } }; SLight light; diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 0218795e01..a21882c6db 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -134,7 +134,7 @@ public: unsigned short getUShort() { return read_le16(); } int getInt() { return read_le32(); } float getFloat() { return read_le32f(); } - Ogre::Vector3 getVector() + Ogre::Vector3 getVector3() { float a[3]; for(size_t i = 0;i < 3;i++) @@ -148,7 +148,7 @@ public: a[i] = getFloat(); return Ogre::Vector4(a); } - Ogre::Matrix3 getMatrix() + Ogre::Matrix3 getMatrix3() { Ogre::Real a[3][3]; for(size_t i = 0;i < 3;i++) @@ -161,10 +161,10 @@ public: Transformation getTrafo() { Transformation t; - t.pos = getVector(); - t.rotation = getMatrix(); + t.pos = getVector3(); + t.rotation = getMatrix3(); t.scale = getFloat(); - t.velocity = getVector(); + t.velocity = getVector3(); return t; } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 240dbe540c..64ef1e3e9c 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -63,9 +63,9 @@ public: if(hasBounds) { nif->getInt(); // always 1 - boundPos = nif->getVector(); - boundRot = nif->getMatrix(); - boundXYZ = nif->getVector(); + boundPos = nif->getVector3(); + boundRot = nif->getMatrix3(); + boundXYZ = nif->getVector3(); } parent = NULL; diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 1b455b14f3..b24e49b479 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -172,10 +172,10 @@ struct S_MaterialProperty void read(NIFFile *nif) { - ambient = nif->getVector(); - diffuse = nif->getVector(); - specular = nif->getVector(); - emissive = nif->getVector(); + ambient = nif->getVector3(); + diffuse = nif->getVector3(); + specular = nif->getVector3(); + emissive = nif->getVector3(); glossiness = nif->getFloat(); alpha = nif->getFloat(); } From 1fef4f2bc217929992771cae66449fcf2365003f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 10 Jul 2012 16:59:26 +0200 Subject: [PATCH 47/51] splitting off credits from readme file --- credits.txt | 39 +++++++++++++++++++++++++++++++++++++++ readme.txt | 41 ----------------------------------------- 2 files changed, 39 insertions(+), 41 deletions(-) create mode 100644 credits.txt diff --git a/credits.txt b/credits.txt new file mode 100644 index 0000000000..8d7cbe7d54 --- /dev/null +++ b/credits.txt @@ -0,0 +1,39 @@ +CREDITS + +Current Developers: +Aleksandar Jovanov +Alexander “Ace” Olofsson +athile +BrotherBrick +Cris “Mirceam” Mihalache +gugus / gus +Jacob “Yacoby” Essex +Jannik “scrawl” Heller +Jason “jhooks” Hooks +Karl-Felix “k1ll” Glatzer +Lukasz “lgro” Gromanowski +Marc “Zini” Zinnschlag +Michael “werdanith” Papageorgiou +Nikolay “corristo” Kasyanov +Pieter “pvdk” van der Kloet +Roman "Kromgart" Melnik +Sebastian “swick” Wick +Sylvain "Garvek" T. + +Retired Developers: +Ardekantur +Armin Preiml +Diggory Hardy +Jan Borsodi +Jan-Peter “peppe” Nilsson +Josua Grawitter +Nicolay Korslund +sergoz +Star-Demon +Yuri Krupenin + +OpenMW: +Thanks to DokterDume for kindly providing us with the Moon and Star logo used as the application icon and project logo. + +Launcher: +Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Files tab. diff --git a/readme.txt b/readme.txt index aa981dba36..327d365861 100644 --- a/readme.txt +++ b/readme.txt @@ -90,47 +90,6 @@ Allowed options: --fallback arg fallback values -CREDITS - -Current Developers: -Aleksandar Jovanov -Alexander “Ace” Olofsson -athile -BrotherBrick -Cris “Mirceam” Mihalache -gugus / gus -Jacob “Yacoby” Essex -Jannik “scrawl” Heller -Jason “jhooks” Hooks -Karl-Felix “k1ll” Glatzer -Lukasz “lgro” Gromanowski -Marc “Zini” Zinnschlag -Michael “werdanith” Papageorgiou -Nikolay “corristo” Kasyanov -Pieter “pvdk” van der Kloet -Roman "Kromgart" Melnik -Sebastian “swick” Wick -Sylvain "Garvek" T. - -Retired Developers: -Ardekantur -Armin Preiml -Diggory Hardy -Jan Borsodi -Jan-Peter “peppe” Nilsson -Josua Grawitter -Nicolay Korslund -sergoz -Star-Demon -Yuri Krupenin - -OpenMW: -Thanks to DokterDume for kindly providing us with the Moon and Star logo used as the application icon and project logo. - -Launcher: -Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Files tab. - - CHANGELOG 0.16.0 From 089ee335884ea2da2fec1845ea50789b03ef21c7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 10 Jul 2012 17:05:52 +0200 Subject: [PATCH 48/51] some readme.txt improvements --- readme.txt | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/readme.txt b/readme.txt index 327d365861..ded9bcd7bc 100644 --- a/readme.txt +++ b/readme.txt @@ -12,8 +12,6 @@ EBGaramond-Regular.ttf: OFL (see OFL.txt for more information) VeraMono.ttf: custom (see Bitstream Vera License.txt for more information) -THIS IS A WORK IN PROGRESS - INSTALLATION @@ -174,7 +172,6 @@ Task #113: Morrowind.ini Importer Task #215: Refactor the sound code Task #216: Update MyGUI - 0.13.0 Bug #145: Fixed sound problems after cell change @@ -232,7 +229,6 @@ Task #131: NPC Activation doesn't work properly Task #144: MWRender cleanup Task #155: cmake cleanup - 0.11.1 Bug #2: Resources loading doesn't work outside of bsa files @@ -259,4 +255,95 @@ Task #14: Replace tabs with 4 spaces Task #18: Move components from global namespace into their own namespace Task #123: refactor header files in components/esm -TODO add old changelog (take pre 0.11.1 changelog from wiki) +0.10.0 + +* NPC dialogue window (not functional yet) +* Collisions with objects +* Refactor the PlayerPos class +* Adjust file locations +* CMake files and test linking for Bullet +* Replace Ogre raycasting test for activation with something more precise +* Adjust player movement according to collision results +* FPS display +* Various Portability Improvements +* Mac OS X support is back! + +0.9.0 + +* Exterior cells loading, unloading and management +* Character Creation GUI +* Character creation +* Make cell names case insensitive when doing internal lookups +* Music player +* NPCs rendering + +0.8.0 + +* GUI +* Complete and working script engine +* In game console +* Sky rendering +* Sound and music +* Tons of smaller stuff + +0.7.0 + +* This release is a complete rewrite in C++. +* All D code has been culled, and all modules have been rewritten. +* The game is now back up to the level of rendering interior cells and moving around, but physics, sound, GUI, and scripting still remain to be ported from the old codebase. + +0.6.0 + +* Coded a GUI system using MyGUI +* Skinned MyGUI to look like Morrowind (work in progress) +* Integrated the Monster script engine +* Rewrote some functions into script code +* Very early MyGUI < > Monster binding +* Fixed Windows sound problems (replaced old openal32.dll) + +0.5.0 + +* Collision detection with Bullet +* Experimental walk & fall character physics +* New key bindings: + * t toggle physics mode (walking, flying, ghost), + * n night eye, brightens the scene +* Fixed incompatability with DMD 1.032 and newer compilers +* * (thanks to tomqyp) +* Various minor changes and updates + +0.4.0 + +* Switched from Audiere to OpenAL +* * (BIG thanks to Chris Robinson) +* Added complete Makefile (again) as a alternative build tool +* More realistic lighting (thanks again to Chris Robinson) +* Various localization fixes tested with Russian and French versions +* Temporary workaround for the Unicode issue: invalid UTF displayed as '?' +* Added ns option to disable sound, for debugging +* Various bug fixes +* Cosmetic changes to placate gdc Wall + +0.3.0 + +* Built and tested on Windows XP +* Partial support for FreeBSD (exceptions do not work) +* You no longer have to download Monster separately +* Made an alternative for building without DSSS (but DSSS still works) +* Renamed main program from 'morro' to 'openmw' +* Made the config system more robust +* Added oc switch for showing Ogre config window on startup +* Removed some config files, these are auto generated when missing. +* Separated plugins.cfg into linux and windows versions. +* Updated Makefile and sources for increased portability +* confirmed to work against OIS 1.0.0 (Ubuntu repository package) + +0.2.0 + +* Compiles with gdc +* Switched to DSSS for building D code +* Includes the program esmtool + +0.1.0 + +first release From 6c73f5e5184303ea0119f12a8a250abac5e89004 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Tue, 10 Jul 2012 22:25:19 +0300 Subject: [PATCH 49/51] Add some translators/reversers to credits.txt --- credits.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/credits.txt b/credits.txt index 8d7cbe7d54..16b41d56a8 100644 --- a/credits.txt +++ b/credits.txt @@ -32,6 +32,25 @@ sergoz Star-Demon Yuri Krupenin +PR team and Translators: +Julien (jvoisin/ap0) Voisin +sirherrbatka +ElderTroll +spyboot +corristo +Okulo +penguinroad +Kingpix + +Reverser and Research: +natirips +Sadler +fragonard +Greendogo +Myckel +modred11 +HiPhish + OpenMW: Thanks to DokterDume for kindly providing us with the Moon and Star logo used as the application icon and project logo. From fb109ec7e2bc57c89afdd46f3ae95e070c97c66c Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Jul 2012 11:30:47 +0200 Subject: [PATCH 50/51] use debug versions of ogre plugins in debug mode --- CMakeLists.txt | 6 ++++++ files/plugins.cfg.linux | 9 ++++----- files/plugins.cfg.mac | 8 ++++---- files/plugins.cfg.win32 | 10 +++++----- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84cef306e0..b561815ca3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,12 @@ set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") +# Debug suffix for plugins +set(DEBUG_SUFFIX "") +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set(DEBUG_SUFFIX "_d") +endif() + # doxygen main page configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") diff --git a/files/plugins.cfg.linux b/files/plugins.cfg.linux index f34621a0f2..bbce1f1b40 100644 --- a/files/plugins.cfg.linux +++ b/files/plugins.cfg.linux @@ -4,9 +4,8 @@ PluginFolder=${OGRE_PLUGIN_DIR_REL} # Define plugins -Plugin=RenderSystem_GL -Plugin=Plugin_ParticleFX -Plugin=Plugin_OctreeSceneManager -Plugin=Plugin_CgProgramManager - +Plugin=RenderSystem_GL${OGRE_RenderSystem_GL_LIBRARIES} +Plugin=Plugin_ParticleFX${DEBUG_SUFFIX} +Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX} +Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX} diff --git a/files/plugins.cfg.mac b/files/plugins.cfg.mac index 3220708321..fac18dc8f8 100644 --- a/files/plugins.cfg.mac +++ b/files/plugins.cfg.mac @@ -4,9 +4,9 @@ PluginFolder=${OGRE_PLUGIN_DIR} # Define plugins -Plugin=RenderSystem_GL.1.8.0 -Plugin=Plugin_ParticleFX.1.8.0 -Plugin=Plugin_OctreeSceneManager.1.8.0 -Plugin=Plugin_CgProgramManager.1.8.0 +Plugin=RenderSystem_GL${DEBUG_SUFFIX}.1.8.0 +Plugin=Plugin_ParticleFX${DEBUG_SUFFIX}.1.8.0 +Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX}.1.8.0 +Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX}.1.8.0 diff --git a/files/plugins.cfg.win32 b/files/plugins.cfg.win32 index ea12c03940..6b4e9ef9dc 100644 --- a/files/plugins.cfg.win32 +++ b/files/plugins.cfg.win32 @@ -4,10 +4,10 @@ PluginFolder=.\ # Define plugins -Plugin=RenderSystem_Direct3D9 -Plugin=RenderSystem_GL -Plugin=Plugin_ParticleFX -Plugin=Plugin_OctreeSceneManager -Plugin=Plugin_CgProgramManager +Plugin=RenderSystem_Direct3D9${DEBUG_SUFFIX} +Plugin=RenderSystem_GL${DEBUG_SUFFIX} +Plugin=Plugin_ParticleFX${DEBUG_SUFFIX} +Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX} +Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX} From 1429c8d5cb088780d6cd969f2eb807f7f41b49e1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Jul 2012 12:43:48 +0200 Subject: [PATCH 51/51] copy&paste mistake --- files/plugins.cfg.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/plugins.cfg.linux b/files/plugins.cfg.linux index bbce1f1b40..7b8d99e8fd 100644 --- a/files/plugins.cfg.linux +++ b/files/plugins.cfg.linux @@ -4,7 +4,7 @@ PluginFolder=${OGRE_PLUGIN_DIR_REL} # Define plugins -Plugin=RenderSystem_GL${OGRE_RenderSystem_GL_LIBRARIES} +Plugin=RenderSystem_GL${DEBUG_SUFFIX} Plugin=Plugin_ParticleFX${DEBUG_SUFFIX} Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX} Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX}