mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 21:39:41 +00:00
Move toMatrix to Nif::Node
This commit is contained in:
parent
f760aebc92
commit
604580d75d
4 changed files with 44 additions and 88 deletions
|
@ -25,6 +25,7 @@
|
||||||
#define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
|
#define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
|
||||||
|
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
#include <osg/Matrixf>
|
||||||
|
|
||||||
// Common types used in NIF files
|
// Common types used in NIF files
|
||||||
|
|
||||||
|
@ -49,6 +50,18 @@ struct Transformation
|
||||||
Matrix3 rotation; // this can contain scale components too, including negative and nonuniform scales
|
Matrix3 rotation; // this can contain scale components too, including negative and nonuniform scales
|
||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
|
osg::Matrixf toMatrix() const
|
||||||
|
{
|
||||||
|
osg::Matrixf transform;
|
||||||
|
transform.setTrans(pos);
|
||||||
|
|
||||||
|
for (int i=0;i<3;++i)
|
||||||
|
for (int j=0;j<3;++j)
|
||||||
|
transform(j,i) = rotation.mValues[i][j] * scale; // NB column/row major difference
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
static const Transformation& getIdentity()
|
static const Transformation& getIdentity()
|
||||||
{
|
{
|
||||||
static const Transformation identity = {
|
static const Transformation identity = {
|
||||||
|
|
|
@ -41,55 +41,16 @@ http://www.gnu.org/licenses/ .
|
||||||
// For warning messages
|
// For warning messages
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Extract a list of keyframe-controlled nodes from a .kf file
|
namespace
|
||||||
// FIXME: this is a similar copy of OgreNifLoader::loadKf
|
|
||||||
void extractControlledNodes(Nif::NIFFilePtr kfFile, std::set<std::string>& controlled)
|
|
||||||
{
|
{
|
||||||
if(kfFile->numRoots() < 1)
|
|
||||||
{
|
|
||||||
kfFile->warn("Found no root nodes in "+kfFile->getFilename()+".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Nif::Record *r = kfFile->getRoot(0);
|
osg::Matrixf getWorldTransform(const Nif::Node *node)
|
||||||
assert(r != NULL);
|
{
|
||||||
|
if(node->parent != NULL)
|
||||||
|
return node->trafo.toMatrix() * getWorldTransform(node->parent);
|
||||||
|
return node->trafo.toMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
if(r->recType != Nif::RC_NiSequenceStreamHelper)
|
|
||||||
{
|
|
||||||
kfFile->warn("First root was not a NiSequenceStreamHelper, but a "+
|
|
||||||
r->recName+".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const Nif::NiSequenceStreamHelper *seq = static_cast<const Nif::NiSequenceStreamHelper*>(r);
|
|
||||||
|
|
||||||
Nif::ExtraPtr extra = seq->extra;
|
|
||||||
if(extra.empty() || extra->recType != Nif::RC_NiTextKeyExtraData)
|
|
||||||
{
|
|
||||||
kfFile->warn("First extra data was not a NiTextKeyExtraData, but a "+
|
|
||||||
(extra.empty() ? std::string("nil") : extra->recName)+".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extra = extra->extra;
|
|
||||||
Nif::ControllerPtr ctrl = seq->controller;
|
|
||||||
for(;!extra.empty() && !ctrl.empty();(extra=extra->extra),(ctrl=ctrl->next))
|
|
||||||
{
|
|
||||||
if(extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController)
|
|
||||||
{
|
|
||||||
kfFile->warn("Unexpected extra data "+extra->recName+" with controller "+ctrl->recName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ctrl->flags & Nif::NiNode::ControllerFlag_Active))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const Nif::NiStringExtraData *strdata = static_cast<const Nif::NiStringExtraData*>(extra.getPtr());
|
|
||||||
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
|
||||||
|
|
||||||
if(key->data.empty())
|
|
||||||
continue;
|
|
||||||
controlled.insert(strdata->string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NifBullet
|
namespace NifBullet
|
||||||
|
@ -133,7 +94,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(kfname))
|
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(kfname))
|
||||||
{
|
{
|
||||||
Nif::NIFFilePtr kf;// (Nif::Cache::getInstance().load(kfname));
|
Nif::NIFFilePtr kf;// (Nif::Cache::getInstance().load(kfname));
|
||||||
extractControlledNodes(kf, mControlledNodes);
|
//extractControlledNodes(kf, mControlledNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nif::Record *r = nif.getRoot(0);
|
Nif::Record *r = nif.getRoot(0);
|
||||||
|
@ -259,7 +220,7 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
else if(node->recType == Nif::RC_NiTriShape)
|
else if(node->recType == Nif::RC_NiTriShape)
|
||||||
{
|
{
|
||||||
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, Ogre::Matrix4()/*node->getWorldTransform()*/, isAnimated);
|
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, getWorldTransform(node), isAnimated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +237,7 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool isAnimated)
|
void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform, bool isAnimated)
|
||||||
{
|
{
|
||||||
assert(shape != NULL);
|
assert(shape != NULL);
|
||||||
|
|
||||||
|
@ -312,18 +273,18 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
|
||||||
childMesh->preallocateVertices(data->vertices.size());
|
childMesh->preallocateVertices(data->vertices.size());
|
||||||
childMesh->preallocateIndices(data->triangles.size());
|
childMesh->preallocateIndices(data->triangles.size());
|
||||||
|
|
||||||
//const std::vector<osg::Vec3f> &vertices = data->vertices;
|
const std::vector<osg::Vec3f> &vertices = data->vertices;
|
||||||
//const std::vector<unsigned short> &triangles = data->triangles;
|
const std::vector<unsigned short> &triangles = data->triangles;
|
||||||
|
|
||||||
for(size_t i = 0;i < data->triangles.size();i+=3)
|
for(size_t i = 0;i < data->triangles.size();i+=3)
|
||||||
{
|
{
|
||||||
//Ogre::Vector3 b1 = vertices[triangles[i+0]];
|
osg::Vec3f b1 = vertices[triangles[i+0]];
|
||||||
//Ogre::Vector3 b2 = vertices[triangles[i+1]];
|
osg::Vec3f b2 = vertices[triangles[i+1]];
|
||||||
//Ogre::Vector3 b3 = vertices[triangles[i+2]];
|
osg::Vec3f b3 = vertices[triangles[i+2]];
|
||||||
//childMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
|
childMesh->addTriangle(btVector3(b1.x(),b1.y(),b1.z()),btVector3(b2.x(),b2.y(),b2.z()),btVector3(b3.x(),b3.y(),b3.z()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
|
TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
|
||||||
|
|
||||||
float scale = shape->trafo.scale;
|
float scale = shape->trafo.scale;
|
||||||
const Nif::Node* parent = shape;
|
const Nif::Node* parent = shape;
|
||||||
|
@ -332,15 +293,15 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
scale *= parent->trafo.scale;
|
scale *= parent->trafo.scale;
|
||||||
}
|
}
|
||||||
//Ogre::Quaternion q = transform.extractQuaternion();
|
osg::Quat q = transform.getRotate();
|
||||||
//Ogre::Vector3 v = transform.getTrans();
|
osg::Vec3f v = transform.getTrans();
|
||||||
//childShape->setLocalScaling(btVector3(scale, scale, scale));
|
childShape->setLocalScaling(btVector3(scale, scale, scale));
|
||||||
|
|
||||||
//btTransform trans(btQuaternion(q.x, q.y, q.z, q.w), btVector3(v.x, v.y, v.z));
|
btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z()));
|
||||||
|
|
||||||
//mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
|
mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
|
||||||
|
|
||||||
//mCompoundShape->addChildShape(trans, childShape);
|
mCompoundShape->addChildShape(trans, childShape);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -349,17 +310,15 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
// Static shape, just transform all vertices into position
|
||||||
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
//const std::vector<osg::Vec3f> &vertices = data->vertices;
|
const std::vector<osg::Vec3f> &vertices = data->vertices;
|
||||||
//const std::vector<unsigned short> &triangles = data->triangles;
|
const std::vector<unsigned short> &triangles = data->triangles;
|
||||||
|
|
||||||
for(size_t i = 0;i < data->triangles.size();i+=3)
|
for(size_t i = 0;i < data->triangles.size();i+=3)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
osg::Vec3f b1 = transform*vertices[triangles[i+0]];
|
osg::Vec3f b1 = transform*vertices[triangles[i+0]];
|
||||||
osg::Vec3f b2 = transform*vertices[triangles[i+1]];
|
osg::Vec3f b2 = transform*vertices[triangles[i+1]];
|
||||||
osg::Vec3f b3 = transform*vertices[triangles[i+2]];
|
osg::Vec3f b3 = transform*vertices[triangles[i+2]];
|
||||||
mStaticMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
|
mStaticMesh->addTriangle(btVector3(b1.x(),b1.y(),b1.z()),btVector3(b2.x(),b2.y(),b2.z()),btVector3(b3.x(),b3.y(),b3.z()));
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <openengine/bullet/BulletShapeLoader.h>
|
#include <openengine/bullet/BulletShapeLoader.h>
|
||||||
|
|
||||||
|
#include <osg/Matrixf>
|
||||||
|
|
||||||
// For warning messages
|
// For warning messages
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@ private:
|
||||||
/**
|
/**
|
||||||
*convert a NiTriShape to a bullet trishape.
|
*convert a NiTriShape to a bullet trishape.
|
||||||
*/
|
*/
|
||||||
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool isAnimated);
|
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated);
|
||||||
|
|
||||||
std::string mResourceName;
|
std::string mResourceName;
|
||||||
|
|
||||||
|
|
|
@ -49,24 +49,6 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
osg::Matrixf toMatrix(const Nif::Transformation& nifTrafo)
|
|
||||||
{
|
|
||||||
osg::Matrixf transform;
|
|
||||||
transform.setTrans(nifTrafo.pos);
|
|
||||||
|
|
||||||
for (int i=0;i<3;++i)
|
|
||||||
for (int j=0;j<3;++j)
|
|
||||||
transform(j,i) = nifTrafo.rotation.mValues[i][j] * nifTrafo.scale; // NB column/row major difference
|
|
||||||
|
|
||||||
return transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Matrixf getWorldTransform(const Nif::Node* node)
|
|
||||||
{
|
|
||||||
if(node->parent != NULL)
|
|
||||||
return toMatrix(node->trafo) * getWorldTransform(node->parent);
|
|
||||||
return toMatrix(node->trafo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getAllNiNodes(const Nif::Node* node, std::vector<int>& outIndices)
|
void getAllNiNodes(const Nif::Node* node, std::vector<int>& outIndices)
|
||||||
{
|
{
|
||||||
|
@ -467,7 +449,7 @@ namespace NifOsg
|
||||||
static osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::TextureManager* textureManager,
|
static osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::TextureManager* textureManager,
|
||||||
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::MatrixTransform> transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo));
|
osg::ref_ptr<osg::MatrixTransform> transformNode = new osg::MatrixTransform(nifNode->trafo.toMatrix());
|
||||||
|
|
||||||
if (nifNode->recType == Nif::RC_NiBillboardNode)
|
if (nifNode->recType == Nif::RC_NiBillboardNode)
|
||||||
{
|
{
|
||||||
|
@ -1072,7 +1054,7 @@ namespace NifOsg
|
||||||
std::pair<unsigned short, float> indexWeight = std::make_pair(weights[j].vertex, weights[j].weight);
|
std::pair<unsigned short, float> indexWeight = std::make_pair(weights[j].vertex, weights[j].weight);
|
||||||
influence.mWeights.insert(indexWeight);
|
influence.mWeights.insert(indexWeight);
|
||||||
}
|
}
|
||||||
influence.mInvBindMatrix = toMatrix(data->bones[i].trafo);
|
influence.mInvBindMatrix = data->bones[i].trafo.toMatrix();
|
||||||
influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius);
|
influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius);
|
||||||
|
|
||||||
map->mMap.insert(std::make_pair(boneName, influence));
|
map->mMap.insert(std::make_pair(boneName, influence));
|
||||||
|
|
Loading…
Reference in a new issue