mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-04 17:40:06 +00:00
Added a basic COLLADA .dae importer mainly to support URDF loading (URDF can refer to COLLADA .dae or STL .stl for mesh support)
It is fairly limited, only supports loading <geometry> with triangulated meshes, no material loading I will extend this with COLLADA Physics support.
This commit is contained in:
parent
5f61473229
commit
579b34d2e0
@ -18,6 +18,8 @@
|
||||
#include "../ImportURDFDemo/ImportURDFSetup.h"
|
||||
#include "../ImportObjDemo/ImportObjSetup.h"
|
||||
#include "../ImportSTLDemo/ImportSTLSetup.h"
|
||||
#include "../ImportColladaDemo/ImportColladaSetup.h"
|
||||
|
||||
#include "../../Demos/SerializeDemo/SerializeSetup.h"
|
||||
#include "../bullet2/MultiBodyDemo/TestJointTorqueSetup.h"
|
||||
#include "../bullet2/CollisionDetection/SupportFuncDemo.h"
|
||||
@ -72,6 +74,12 @@ static BulletDemoInterface* MyImportSTLCreateFunc(CommonGraphicsApp* app)
|
||||
return new BasicDemo(app, physicsSetup);
|
||||
}
|
||||
|
||||
static BulletDemoInterface* MyImportColladaCreateFunc(CommonGraphicsApp* app)
|
||||
{
|
||||
CommonPhysicsSetup* physicsSetup = new ImportColladaSetup(app);
|
||||
return new BasicDemo(app, physicsSetup);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -92,7 +100,6 @@ static BulletDemoEntry allDemos[]=
|
||||
//{"emptydemo",EmptyBulletDemo::MyCreateFunc},
|
||||
{0,"API Demos", 0},
|
||||
|
||||
|
||||
{1,"BasicDemo",BasicDemo::MyCreateFunc},
|
||||
{ 1, "CcdDemo", MyCcdPhysicsDemoCreateFunc },
|
||||
{ 1, "Kinematic", MyKinematicObjectCreateFunc },
|
||||
@ -100,11 +107,12 @@ static BulletDemoEntry allDemos[]=
|
||||
{ 1, "LuaDemo",LuaDemoCreateFunc},
|
||||
|
||||
{0,"File Formats", 0},
|
||||
//@todo(erwincoumans) { 1, "bullet", MyImportSTLCreateFunc},
|
||||
|
||||
{ 1, ".bullet",MySerializeCreateFunc},
|
||||
{ 1, "Wavefront Obj", MyImportObjCreateFunc},
|
||||
{ 1, "URDF", MyImportUrdfCreateFunc },
|
||||
{ 1, "STL", MyImportSTLCreateFunc},
|
||||
{ 1, "COLLADA", MyImportColladaCreateFunc},
|
||||
|
||||
/* {1,"ChainDemo",ChainDemo::MyCreateFunc},
|
||||
// {0, "Stress tests", 0 },
|
||||
|
@ -43,6 +43,8 @@ SET(App_AllBullet2Demos_SRCS
|
||||
../ImportURDFDemo/ImportURDFSetup.h
|
||||
../ImportObjDemo/ImportObjSetup.cpp
|
||||
../ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
|
||||
../ImportColladaDemo/ImportColladaSetup.cpp
|
||||
../ImportColladaDemo/LoadMeshFromCollada.cpp
|
||||
../ImportSTLDemo/ImportSTLSetup.cpp
|
||||
../Wavefront/tiny_obj_loader.cpp
|
||||
../Wavefront/tiny_obj_loader.h
|
||||
|
@ -57,7 +57,9 @@
|
||||
"../../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp",
|
||||
"../../Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp",
|
||||
"../bullet2/ConstraintDemo/ConstraintPhysicsSetup.cpp",
|
||||
"../bullet2/ConstraintDemo/ConstraintPhysicsSetup.h",
|
||||
"../bullet2/ConstraintDemo/ConstraintPhysicsSetup.h",
|
||||
"../ImportColladaDemo/LoadMeshFromCollada.cpp",
|
||||
"../ImportColladaDemo/ImportColladaSetup.cpp",
|
||||
"../ImportURDFDemo/ImportURDFSetup.cpp",
|
||||
"../ImportObjDemo/ImportObjSetup.cpp",
|
||||
"../ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
|
||||
|
35
Demos3/ImportColladaDemo/ColladaGraphicsInstance.h
Normal file
35
Demos3/ImportColladaDemo/ColladaGraphicsInstance.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
#ifndef COLLADA_GRAPHICS_INSTANCE_H
|
||||
#define COLLADA_GRAPHICS_INSTANCE_H
|
||||
|
||||
#include "btMatrix4x4.h"
|
||||
|
||||
struct ColladaGraphicsInstance
|
||||
{
|
||||
ColladaGraphicsInstance()
|
||||
:m_shapeIndex(-1)
|
||||
{
|
||||
m_worldTransform.setIdentity();
|
||||
}
|
||||
btMatrix4x4 m_worldTransform;
|
||||
int m_shapeIndex;//could be index into array of GLInstanceGraphicsShape
|
||||
float m_color[4];
|
||||
};
|
||||
|
||||
#endif //COLLADA_GRAPHICS_INSTANCE_H
|
156
Demos3/ImportColladaDemo/ImportColladaSetup.cpp
Normal file
156
Demos3/ImportColladaDemo/ImportColladaSetup.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
|
||||
#include "ImportColladaSetup.h"
|
||||
#include <vector>
|
||||
#include "OpenGLWindow/GLInstancingRenderer.h"
|
||||
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "OpenGLWindow/SimpleOpenGL3App.h"
|
||||
#include "LoadMeshFromCollada.h"
|
||||
#include "Bullet3Common/b3FileUtils.h"
|
||||
|
||||
ImportColladaSetup::ImportColladaSetup(CommonGraphicsApp* app)
|
||||
:m_app(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ImportColladaSetup::~ImportColladaSetup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int ColladaGraphicsInstanceSortfnc(const ColladaGraphicsInstance& a,const ColladaGraphicsInstance& b)
|
||||
{
|
||||
if (a.m_shapeIndex<b.m_shapeIndex) return +1;
|
||||
if (a.m_shapeIndex>b.m_shapeIndex) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ImportColladaSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
|
||||
{
|
||||
gfxBridge.setUpAxis(1);
|
||||
this->createEmptyDynamicsWorld();
|
||||
gfxBridge.createPhysicsDebugDrawer(m_dynamicsWorld);
|
||||
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
||||
|
||||
static int fileIndex = 0;
|
||||
|
||||
const char* fileNames[] = {
|
||||
"duck.dae",
|
||||
"seymourplane_triangulate.dae",
|
||||
};
|
||||
const char* fileName = fileNames[fileIndex];
|
||||
int numFiles = sizeof(fileNames)/sizeof(const char*);
|
||||
|
||||
char relativeFileName[1024];
|
||||
|
||||
b3FileUtils f;
|
||||
if (!f.findFile(fileName,relativeFileName,1024))
|
||||
return;
|
||||
|
||||
btVector3 shift(0,0,0);
|
||||
btVector3 scaling(1,1,1);
|
||||
// int index=10;
|
||||
|
||||
fileIndex++;
|
||||
if (fileIndex>=numFiles)
|
||||
{
|
||||
fileIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
btAlignedObjectArray<GLInstanceGraphicsShape> visualShapes;
|
||||
btAlignedObjectArray<ColladaGraphicsInstance> visualShapeInstances;
|
||||
|
||||
btScalar unitMeterScaling(1);
|
||||
btTransform upAxisTrans;
|
||||
upAxisTrans.setIdentity();
|
||||
|
||||
|
||||
LoadMeshFromCollada(relativeFileName, visualShapes, visualShapeInstances,upAxisTrans,unitMeterScaling);
|
||||
|
||||
//at the moment our graphics engine requires instances that share the same visual shape to be added right after registering the shape
|
||||
//so perform a sort, just to be sure
|
||||
visualShapeInstances.quickSort(ColladaGraphicsInstanceSortfnc);
|
||||
|
||||
for (int i=0;i<visualShapeInstances.size();i++)
|
||||
{
|
||||
ColladaGraphicsInstance* instance = &visualShapeInstances[i];
|
||||
GLInstanceGraphicsShape* gfxShape = &visualShapes[instance->m_shapeIndex];
|
||||
btVector3 position(0,0,0);// = scaling*btVector3(instance->m_pos[0],instance->m_pos[1],instance->m_pos[2]);
|
||||
btQuaternion orn(0,0,0,1);//instance->m_orn[0],instance->m_orn[1],instance->m_orn[2],instance->m_orn[3]);
|
||||
|
||||
//sort the visualShapeInstances, then iterate etc
|
||||
//void LoadMeshFromCollada(const char* relativeFileName,
|
||||
//btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes,
|
||||
//btAlignedObjectArray<GLInstanceGraphicsInstance> visualShapeInstances);
|
||||
|
||||
if (gfxShape)
|
||||
{
|
||||
//btTransform trans;
|
||||
//trans.setIdentity();
|
||||
//trans.setRotation(btQuaternion(btVector3(1,0,0),SIMD_HALF_PI));
|
||||
|
||||
btVector3 color(0,0,1);
|
||||
|
||||
b3AlignedObjectArray<GLInstanceVertex> verts;
|
||||
verts.resize(gfxShape->m_vertices->size());
|
||||
|
||||
for (int i=0;i<gfxShape->m_vertices->size();i++)
|
||||
{
|
||||
verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0];
|
||||
verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1];
|
||||
verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2];
|
||||
verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0];
|
||||
verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1];
|
||||
verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0];
|
||||
verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1];
|
||||
verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2];
|
||||
verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3];
|
||||
}
|
||||
|
||||
//compensate upAxisTrans and unitMeterScaling here
|
||||
btMatrix4x4 upAxisMat;
|
||||
upAxisMat.setPureRotation(upAxisTrans.getRotation());
|
||||
btMatrix4x4 unitMeterScalingMat;
|
||||
unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling,unitMeterScaling,unitMeterScaling));
|
||||
btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform;
|
||||
//btMatrix4x4 worldMat = instance->m_worldTransform;
|
||||
for(int v=0;v<verts.size();v++)
|
||||
{
|
||||
btVector3 pos(verts[v].xyzw[0],verts[v].xyzw[1],verts[v].xyzw[2]);
|
||||
pos = worldMat*pos;
|
||||
verts[v].xyzw[0] = pos[0];
|
||||
verts[v].xyzw[1] = pos[1];
|
||||
verts[v].xyzw[2] = pos[2];
|
||||
}
|
||||
|
||||
int shapeId = m_app->m_renderer->registerShape(&verts[0].xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices);
|
||||
|
||||
//btVector3 instanceScaling(instance->m_scaling[0],instance->m_scaling[1],instance->m_scaling[2]);
|
||||
m_app->m_renderer->registerGraphicsInstance(shapeId,position,orn,color,scaling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
Demos3/ImportColladaDemo/ImportColladaSetup.h
Normal file
35
Demos3/ImportColladaDemo/ImportColladaSetup.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
|
||||
#ifndef IMPORT_COLLADA_SETUP_H
|
||||
#define IMPORT_COLLADA_SETUP_H
|
||||
|
||||
|
||||
#include "Bullet3AppSupport/CommonRigidBodySetup.h"
|
||||
|
||||
class ImportColladaSetup : public CommonRigidBodySetup
|
||||
{
|
||||
struct CommonGraphicsApp* m_app;
|
||||
public:
|
||||
ImportColladaSetup(CommonGraphicsApp* app);
|
||||
virtual ~ImportColladaSetup();
|
||||
|
||||
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge);
|
||||
};
|
||||
|
||||
#endif //IMPORT_COLLADA_SETUP_H
|
548
Demos3/ImportColladaDemo/LoadMeshFromCollada.cpp
Normal file
548
Demos3/ImportColladaDemo/LoadMeshFromCollada.cpp
Normal file
@ -0,0 +1,548 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
|
||||
#include "LoadMeshFromCollada.h"
|
||||
#include <stdio.h> //fopen
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include <string>
|
||||
#include "OpenGLWindow/OpenGLInclude.h"
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
#include "Bullet3Common/b3FileUtils.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
#include <assert.h>
|
||||
#include "btMatrix4x4.h"
|
||||
|
||||
|
||||
struct VertexSource
|
||||
{
|
||||
std::string m_positionArrayId;
|
||||
std::string m_normalArrayId;
|
||||
};
|
||||
|
||||
struct TokenFloatArray
|
||||
{
|
||||
btAlignedObjectArray<float>& m_values;
|
||||
TokenFloatArray(btAlignedObjectArray<float>& floatArray)
|
||||
:m_values(floatArray) {
|
||||
}
|
||||
inline void add(const char* token)
|
||||
{
|
||||
float v = atof(token);
|
||||
m_values.push_back(v);
|
||||
}
|
||||
};
|
||||
struct TokenIntArray
|
||||
{
|
||||
btAlignedObjectArray<int>& m_values;
|
||||
TokenIntArray(btAlignedObjectArray<int>& intArray)
|
||||
:m_values(intArray) {
|
||||
}
|
||||
inline void add(const char* token)
|
||||
{
|
||||
float v = atoi(token);
|
||||
m_values.push_back(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AddToken>
|
||||
void tokenize(const std::string& str, AddToken& tokenAdder, const std::string& delimiters = " ")
|
||||
{
|
||||
std::string::size_type pos, lastPos = 0;
|
||||
while(true)
|
||||
{
|
||||
pos = str.find_first_of(delimiters, lastPos);
|
||||
if(pos == std::string::npos)
|
||||
{
|
||||
pos = str.length();
|
||||
if(pos != lastPos)
|
||||
{
|
||||
tokenAdder.add(str.data()+lastPos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pos != lastPos)
|
||||
{
|
||||
tokenAdder.add(str.data()+lastPos);
|
||||
}
|
||||
}
|
||||
lastPos = pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void readFloatArray(TiXmlElement* source, btAlignedObjectArray<float>& floatArray, int& componentStride)
|
||||
{
|
||||
int numVals, stride;
|
||||
TiXmlElement* array = source->FirstChildElement("float_array");
|
||||
if(array)
|
||||
{
|
||||
componentStride = 1;
|
||||
if (source->FirstChildElement("technique_common")->FirstChildElement("accessor")->QueryIntAttribute("stride", &stride)!= TIXML_NO_ATTRIBUTE)
|
||||
{
|
||||
componentStride = stride;
|
||||
}
|
||||
array->QueryIntAttribute("count", &numVals);
|
||||
TokenFloatArray adder(floatArray);
|
||||
floatArray.reserve(numVals);
|
||||
tokenize(array->GetText(),adder);
|
||||
assert(floatArray.size() == numVals);
|
||||
}
|
||||
}
|
||||
|
||||
btVector3 getVector3FromXmlText(const char* text)
|
||||
{
|
||||
btVector3 vec(0,0,0);
|
||||
btAlignedObjectArray<float> floatArray;
|
||||
TokenFloatArray adder(floatArray);
|
||||
floatArray.reserve(3);
|
||||
tokenize(text,adder);
|
||||
assert(floatArray.size() == 3);
|
||||
if (floatArray.size()==3)
|
||||
{
|
||||
vec.setValue(floatArray[0],floatArray[1],floatArray[2]);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
btVector4 getVector4FromXmlText(const char* text)
|
||||
{
|
||||
btVector4 vec(0,0,0,0);
|
||||
btAlignedObjectArray<float> floatArray;
|
||||
TokenFloatArray adder(floatArray);
|
||||
floatArray.reserve(4);
|
||||
tokenize(text,adder);
|
||||
assert(floatArray.size() == 4);
|
||||
if (floatArray.size()==4)
|
||||
{
|
||||
vec.setValue(floatArray[0],floatArray[1],floatArray[2],floatArray[3]);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
void readLibraryGeometries(TiXmlDocument& doc, btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes, btHashMap<btHashString,int>& name2Shape, float extraScaling)
|
||||
{
|
||||
btHashMap<btHashString,TiXmlElement* > allSources;
|
||||
btHashMap<btHashString,VertexSource> vertexSources;
|
||||
for(TiXmlElement* geometry = doc.RootElement()->FirstChildElement("library_geometries")->FirstChildElement("geometry");
|
||||
geometry != NULL; geometry = geometry->NextSiblingElement("geometry"))
|
||||
{
|
||||
btAlignedObjectArray<btVector3> vertexPositions;
|
||||
btAlignedObjectArray<btVector3> vertexNormals;
|
||||
btAlignedObjectArray<int> indices;
|
||||
|
||||
const char* geometryName = geometry->Attribute("id");
|
||||
for (TiXmlElement* mesh = geometry->FirstChildElement("mesh");(mesh != NULL); mesh = mesh->NextSiblingElement("mesh"))
|
||||
{
|
||||
TiXmlElement* vertices2 = mesh->FirstChildElement("vertices");
|
||||
|
||||
for (TiXmlElement* source = mesh->FirstChildElement("source");source != NULL;source = source->NextSiblingElement("source"))
|
||||
{
|
||||
const char* srcId= source->Attribute("id");
|
||||
// printf("source id=%s\n",srcId);
|
||||
allSources.insert(srcId,source);
|
||||
}
|
||||
const char* vertexId = vertices2->Attribute("id");
|
||||
//printf("vertices id=%s\n",vertexId);
|
||||
VertexSource vs;
|
||||
for(TiXmlElement* input = vertices2->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input"))
|
||||
{
|
||||
const char* sem = input->Attribute("semantic");
|
||||
std::string semName(sem);
|
||||
// printf("sem=%s\n",sem);
|
||||
const char* src = input->Attribute("source");
|
||||
// printf("src=%s\n",src);
|
||||
const char* srcIdRef = input->Attribute("source");
|
||||
std::string source_name;
|
||||
source_name = std::string(srcIdRef);
|
||||
source_name = source_name.erase(0, 1);
|
||||
if (semName=="POSITION")
|
||||
{
|
||||
vs.m_positionArrayId = source_name;
|
||||
}
|
||||
if (semName=="NORMAL")
|
||||
{
|
||||
vs.m_normalArrayId = source_name;
|
||||
}
|
||||
}
|
||||
vertexSources.insert(vertexId,vs);
|
||||
|
||||
for (TiXmlElement* primitive = mesh->FirstChildElement("triangles"); primitive; primitive = primitive->NextSiblingElement("triangles"))
|
||||
{
|
||||
std::string positionSourceName;
|
||||
std::string normalSourceName;
|
||||
int primitiveCount;
|
||||
primitive->QueryIntAttribute("count", &primitiveCount);
|
||||
bool positionAndNormalInVertex=false;
|
||||
int indexStride=1;
|
||||
int posOffset = 0;
|
||||
int normalOffset = 0;
|
||||
int numIndices = 0;
|
||||
{
|
||||
for (TiXmlElement* input = primitive->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input"))
|
||||
{
|
||||
const char* sem = input->Attribute("semantic");
|
||||
std::string semName(sem);
|
||||
int offset = atoi(input->Attribute("offset"));
|
||||
if ((offset+1)>indexStride)
|
||||
indexStride=offset+1;
|
||||
//printf("sem=%s\n",sem);
|
||||
const char* src = input->Attribute("source");
|
||||
//printf("src=%s\n",src);
|
||||
const char* srcIdRef = input->Attribute("source");
|
||||
std::string source_name;
|
||||
source_name = std::string(srcIdRef);
|
||||
source_name = source_name.erase(0, 1);
|
||||
|
||||
if (semName=="VERTEX")
|
||||
{
|
||||
//now we have POSITION and possibly NORMAL too, using same index array (<p>)
|
||||
VertexSource* vs = vertexSources[source_name.c_str()];
|
||||
if (vs->m_positionArrayId.length())
|
||||
{
|
||||
positionSourceName = vs->m_positionArrayId;
|
||||
posOffset = offset;
|
||||
}
|
||||
if (vs->m_normalArrayId.length())
|
||||
{
|
||||
normalSourceName = vs->m_normalArrayId;
|
||||
normalOffset = offset;
|
||||
positionAndNormalInVertex = true;
|
||||
}
|
||||
}
|
||||
if (semName=="NORMAL")
|
||||
{
|
||||
btAssert(normalSourceName.length()==0);
|
||||
normalSourceName = source_name;
|
||||
normalOffset = offset;
|
||||
positionAndNormalInVertex = false;
|
||||
}
|
||||
}
|
||||
numIndices = primitiveCount * 3;
|
||||
}
|
||||
btAlignedObjectArray<float> positionFloatArray;
|
||||
int posStride=1;
|
||||
TiXmlElement** sourcePtr = allSources[positionSourceName.c_str()];
|
||||
if (sourcePtr)
|
||||
{
|
||||
readFloatArray(*sourcePtr,positionFloatArray, posStride);
|
||||
}
|
||||
btAlignedObjectArray<float> normalFloatArray;
|
||||
int normalStride=1;
|
||||
sourcePtr = allSources[normalSourceName.c_str()];
|
||||
if (sourcePtr)
|
||||
{
|
||||
readFloatArray(*sourcePtr,normalFloatArray,normalStride);
|
||||
}
|
||||
btAlignedObjectArray<int> curIndices;
|
||||
curIndices.reserve(numIndices*indexStride);
|
||||
TokenIntArray adder(curIndices);
|
||||
tokenize(primitive->FirstChildElement("p")->GetText(),adder);
|
||||
assert(curIndices.size() == numIndices*indexStride);
|
||||
int indexOffset = vertexPositions.size();
|
||||
|
||||
for(int index=0; index<numIndices; index++)
|
||||
{
|
||||
int posIndex = curIndices[index*indexStride+posOffset];
|
||||
int normalIndex = curIndices[index*indexStride+normalOffset];
|
||||
vertexPositions.push_back(btVector3(extraScaling*positionFloatArray[posIndex*3+0],
|
||||
extraScaling*positionFloatArray[posIndex*3+1],
|
||||
extraScaling*positionFloatArray[posIndex*3+2]));
|
||||
|
||||
vertexNormals.push_back(btVector3(normalFloatArray[normalIndex*3+0],
|
||||
normalFloatArray[normalIndex*3+1],
|
||||
normalFloatArray[normalIndex*3+2]));
|
||||
}
|
||||
int curNumIndices = indices.size();
|
||||
indices.resize(curNumIndices+numIndices);
|
||||
for(int index=0; index<numIndices; index++)
|
||||
{
|
||||
indices[curNumIndices+index] = index+indexOffset;
|
||||
}
|
||||
}//if(primitive != NULL)
|
||||
}//for each mesh
|
||||
|
||||
int shapeIndex = visualShapes.size();
|
||||
GLInstanceGraphicsShape& visualShape = visualShapes.expand();
|
||||
{
|
||||
visualShape.m_vertices = new b3AlignedObjectArray<GLInstanceVertex>;
|
||||
visualShape.m_indices = new b3AlignedObjectArray<int>;
|
||||
int indexBase = 0;
|
||||
|
||||
btAssert(vertexNormals.size()==vertexPositions.size());
|
||||
for (int v=0;v<vertexPositions.size();v++)
|
||||
{
|
||||
GLInstanceVertex vtx;
|
||||
vtx.xyzw[0] = vertexPositions[v].x();
|
||||
vtx.xyzw[1] = vertexPositions[v].y();
|
||||
vtx.xyzw[2] = vertexPositions[v].z();
|
||||
vtx.xyzw[3] = 1.f;
|
||||
vtx.normal[0] = vertexNormals[v].x();
|
||||
vtx.normal[1] = vertexNormals[v].y();
|
||||
vtx.normal[2] = vertexNormals[v].z();
|
||||
vtx.uv[0] = 0.5f;
|
||||
vtx.uv[1] = 0.5f;
|
||||
visualShape.m_vertices->push_back(vtx);
|
||||
}
|
||||
|
||||
for (int index=0;index<indices.size();index++)
|
||||
{
|
||||
visualShape.m_indices->push_back(indices[index]+indexBase);
|
||||
}
|
||||
|
||||
|
||||
printf(" index_count =%dand vertexPositions.size=%d\n",indices.size(), vertexPositions.size());
|
||||
indexBase=visualShape.m_vertices->size();
|
||||
visualShape.m_numIndices = visualShape.m_indices->size();
|
||||
visualShape.m_numvertices = visualShape.m_vertices->size();
|
||||
}
|
||||
printf("geometry name=%s\n",geometryName);
|
||||
name2Shape.insert(geometryName,shapeIndex);
|
||||
|
||||
|
||||
}//for each geometry
|
||||
}
|
||||
|
||||
void readNodeHierarchy(TiXmlElement* node,btHashMap<btHashString,int>& name2Shape, btAlignedObjectArray<ColladaGraphicsInstance>& visualShapeInstances, const btMatrix4x4& parentTransMat)
|
||||
{
|
||||
const char* nodeName = node->Attribute("id");
|
||||
printf("processing node %s\n", nodeName);
|
||||
|
||||
|
||||
btMatrix4x4 nodeTrans;
|
||||
nodeTrans.setIdentity();
|
||||
|
||||
///todo(erwincoumans) we probably have to read the elements 'translate', 'scale', 'rotate' and 'matrix' in-order and accumulate them...
|
||||
{
|
||||
for (TiXmlElement* transElem = node->FirstChildElement("matrix");transElem;transElem=node->NextSiblingElement("matrix"))
|
||||
{
|
||||
if (transElem->GetText())
|
||||
{
|
||||
btAlignedObjectArray<float> floatArray;
|
||||
TokenFloatArray adder(floatArray);
|
||||
tokenize(transElem->GetText(),adder);
|
||||
if (floatArray.size()==16)
|
||||
{
|
||||
btMatrix4x4 t(floatArray[0],floatArray[1],floatArray[2],floatArray[3],
|
||||
floatArray[4],floatArray[5],floatArray[6],floatArray[7],
|
||||
floatArray[8],floatArray[9],floatArray[10],floatArray[11],
|
||||
floatArray[12],floatArray[13],floatArray[14],floatArray[15]);
|
||||
|
||||
nodeTrans = nodeTrans*t;
|
||||
} else
|
||||
{
|
||||
printf("Error: expected 16 elements in a <matrix> element, skipping\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (TiXmlElement* transElem = node->FirstChildElement("translate");transElem;transElem=node->NextSiblingElement("translate"))
|
||||
{
|
||||
if (transElem->GetText())
|
||||
{
|
||||
btVector3 pos = getVector3FromXmlText(transElem->GetText());
|
||||
//nodePos+= unitScaling*parentScaling*pos;
|
||||
btMatrix4x4 t;
|
||||
t.setPureTranslation(pos);
|
||||
nodeTrans = nodeTrans*t;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for(TiXmlElement* scaleElem = node->FirstChildElement("scale");
|
||||
scaleElem!= NULL; scaleElem= node->NextSiblingElement("scale"))
|
||||
{
|
||||
if (scaleElem->GetText())
|
||||
{
|
||||
btVector3 scaling = getVector3FromXmlText(scaleElem->GetText());
|
||||
btMatrix4x4 t;
|
||||
t.setPureScaling(scaling);
|
||||
nodeTrans = nodeTrans*t;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for(TiXmlElement* rotateElem = node->FirstChildElement("rotate");
|
||||
rotateElem!= NULL; rotateElem= node->NextSiblingElement("rotate"))
|
||||
{
|
||||
if (rotateElem->GetText())
|
||||
{
|
||||
//accumulate orientation
|
||||
btVector4 rotate = getVector4FromXmlText(rotateElem->GetText());
|
||||
btQuaternion orn(btVector3(rotate),btRadians(rotate[3]));//COLLADA DAE rotate is in degrees, convert to radians
|
||||
btMatrix4x4 t;
|
||||
t.setPureRotation(orn);
|
||||
nodeTrans = nodeTrans*t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeTrans = parentTransMat*nodeTrans;
|
||||
|
||||
for (TiXmlElement* instanceGeom = node->FirstChildElement("instance_geometry");
|
||||
instanceGeom!=0;
|
||||
instanceGeom=instanceGeom->NextSiblingElement("instance_geometry"))
|
||||
{
|
||||
const char* geomUrl = instanceGeom->Attribute("url");
|
||||
printf("node referring to geom %s\n", geomUrl);
|
||||
geomUrl++;
|
||||
int* shapeIndexPtr = name2Shape[geomUrl];
|
||||
if (shapeIndexPtr)
|
||||
{
|
||||
int index = *shapeIndexPtr;
|
||||
printf("found geom with index %d\n", *shapeIndexPtr);
|
||||
ColladaGraphicsInstance& instance = visualShapeInstances.expand();
|
||||
instance.m_shapeIndex = *shapeIndexPtr;
|
||||
instance.m_worldTransform = nodeTrans;
|
||||
} else
|
||||
{
|
||||
printf("geom not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
for(TiXmlElement* childNode = node->FirstChildElement("node");
|
||||
childNode!= NULL; childNode = childNode->NextSiblingElement("node"))
|
||||
{
|
||||
readNodeHierarchy(childNode,name2Shape,visualShapeInstances, nodeTrans);
|
||||
}
|
||||
}
|
||||
void readVisualSceneInstanceGeometries(TiXmlDocument& doc, btHashMap<btHashString,int>& name2Shape, btAlignedObjectArray<ColladaGraphicsInstance>& visualShapeInstances)
|
||||
{
|
||||
btHashMap<btHashString,TiXmlElement* > allVisualScenes;
|
||||
|
||||
TiXmlElement* libVisualScenes = doc.RootElement()->FirstChildElement("library_visual_scenes");
|
||||
if (libVisualScenes==0)
|
||||
return;
|
||||
|
||||
{
|
||||
for(TiXmlElement* scene = libVisualScenes->FirstChildElement("visual_scene");
|
||||
scene != NULL; scene = scene->NextSiblingElement("visual_scene"))
|
||||
{
|
||||
const char* sceneName = scene->Attribute("id");
|
||||
allVisualScenes.insert(sceneName,scene);
|
||||
}
|
||||
}
|
||||
|
||||
TiXmlElement* scene = 0;
|
||||
{
|
||||
TiXmlElement* scenes = doc.RootElement()->FirstChildElement("scene");
|
||||
if (scenes)
|
||||
{
|
||||
TiXmlElement* instanceSceneReference = scenes->FirstChildElement("instance_visual_scene");
|
||||
if (instanceSceneReference)
|
||||
{
|
||||
const char* instanceSceneUrl = instanceSceneReference->Attribute("url");
|
||||
TiXmlElement** sceneInstancePtr = allVisualScenes[instanceSceneUrl+1];//skip #
|
||||
if (sceneInstancePtr)
|
||||
{
|
||||
scene = *sceneInstancePtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scene)
|
||||
{
|
||||
for(TiXmlElement* node = scene->FirstChildElement("node");
|
||||
node != NULL; node = node->NextSiblingElement("node"))
|
||||
{
|
||||
btMatrix4x4 identity;
|
||||
identity.setIdentity();
|
||||
btVector3 identScaling(1,1,1);
|
||||
readNodeHierarchy(node,name2Shape,visualShapeInstances, identity);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void getUnitMeterScalingAndUpAxisTransform(TiXmlDocument& doc, btTransform& tr, float& unitMeterScaling)
|
||||
{
|
||||
TiXmlElement* unitMeter = doc.RootElement()->FirstChildElement("asset")->FirstChildElement("unit");
|
||||
if (unitMeter)
|
||||
{
|
||||
const char* meterText = unitMeter->Attribute("meter");
|
||||
printf("meterText=%s\n", meterText);
|
||||
unitMeterScaling = atof(meterText);
|
||||
}
|
||||
|
||||
TiXmlElement* upAxisElem = doc.RootElement()->FirstChildElement("asset")->FirstChildElement("up_axis");
|
||||
if (upAxisElem)
|
||||
{
|
||||
std::string upAxisTxt = upAxisElem->GetText();
|
||||
if (upAxisTxt == "X_UP")
|
||||
{
|
||||
btQuaternion y2x(btVector3(0,0,1),SIMD_HALF_PI);
|
||||
tr.setRotation(y2x);
|
||||
}
|
||||
if (upAxisTxt == "Y_UP")
|
||||
{
|
||||
//assume Y_UP for now, to be compatible with assimp?
|
||||
}
|
||||
if (upAxisTxt == "Z_UP")
|
||||
{
|
||||
btQuaternion y2z(btVector3(1,0,0),-SIMD_HALF_PI);
|
||||
tr.setRotation(y2z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadMeshFromCollada(const char* relativeFileName, btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes, btAlignedObjectArray<ColladaGraphicsInstance>& visualShapeInstances, btTransform& upAxisTransform, float& unitMeterScaling)
|
||||
{
|
||||
|
||||
GLInstanceGraphicsShape* instance = 0;
|
||||
|
||||
//usually COLLADA files don't have that many visual geometries/shapes
|
||||
visualShapes.reserve(32);
|
||||
|
||||
float extraScaling = 1;//0.01;
|
||||
btHashMap<btHashString, int> name2ShapeIndex;
|
||||
b3FileUtils f;
|
||||
char filename[1024];
|
||||
if (!f.findFile(relativeFileName,filename,1024))
|
||||
{
|
||||
printf("File not found: %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
TiXmlDocument doc(filename);
|
||||
if (!doc.LoadFile())
|
||||
return;
|
||||
|
||||
//We need units to be in meter, so apply a scaling using the asset/units meter
|
||||
unitMeterScaling=1;
|
||||
upAxisTransform.setIdentity();
|
||||
|
||||
//Also we can optionally compensate all transforms using the asset/up_axis as well as unit meter scaling
|
||||
getUnitMeterScalingAndUpAxisTransform(doc, upAxisTransform, unitMeterScaling);
|
||||
|
||||
btMatrix4x4 ident;
|
||||
ident.setIdentity();
|
||||
|
||||
readLibraryGeometries(doc, visualShapes, name2ShapeIndex, extraScaling);
|
||||
|
||||
readVisualSceneInstanceGeometries(doc, name2ShapeIndex, visualShapeInstances);
|
||||
|
||||
}
|
||||
|
35
Demos3/ImportColladaDemo/LoadMeshFromCollada.h
Normal file
35
Demos3/ImportColladaDemo/LoadMeshFromCollada.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LOAD_MESH_FROM_COLLADA_H
|
||||
#define LOAD_MESH_FROM_COLLADA_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "OpenGLWindow/GLInstanceGraphicsShape.h"
|
||||
#include "ColladaGraphicsInstance.h"
|
||||
|
||||
|
||||
void LoadMeshFromCollada(const char* relativeFileName,
|
||||
btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes,
|
||||
btAlignedObjectArray<ColladaGraphicsInstance>& visualShapeInstances,
|
||||
btTransform& upAxisTrans,
|
||||
float& unitMeterScaling);
|
||||
|
||||
|
||||
#endif //LOAD_MESH_FROM_COLLADA_H
|
156
Demos3/ImportColladaDemo/btMatrix4x4.h
Normal file
156
Demos3/ImportColladaDemo/btMatrix4x4.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
Bullet Collision Detection and Physics Library http://bulletphysics.org
|
||||
This file is Copyright (c) 2014 Google Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
//original author: Erwin Coumans
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MATRIX4x4_H
|
||||
#define MATRIX4x4_H
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
///This 4x4 matrix class is extremely limited, just created for the purpose of accumulating transform matrices in COLLADA .dae files
|
||||
ATTRIBUTE_ALIGNED16(class) btMatrix4x4
|
||||
{
|
||||
btVector4 m_el[4];
|
||||
public:
|
||||
|
||||
btMatrix4x4()
|
||||
{
|
||||
}
|
||||
btMatrix4x4(const btScalar& xx, const btScalar& xy, const btScalar& xz,const btScalar& xw,
|
||||
const btScalar& yx, const btScalar& yy, const btScalar& yz,const btScalar& yw,
|
||||
const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw,
|
||||
const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww)
|
||||
{
|
||||
setValue(xx, xy, xz, xw,
|
||||
yx, yy, yz, yw,
|
||||
zx, zy, zz,zw,
|
||||
wx, wy, wz,ww);
|
||||
}
|
||||
|
||||
~btMatrix4x4()
|
||||
{
|
||||
}
|
||||
|
||||
inline void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,const btScalar& xw,
|
||||
const btScalar& yx, const btScalar& yy, const btScalar& yz,const btScalar& yw,
|
||||
const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw,
|
||||
const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww)
|
||||
{
|
||||
m_el[0].setValue(xx,xy,xz,xw);
|
||||
m_el[1].setValue(yx,yy,yz,yw);
|
||||
m_el[2].setValue(zx,zy,zz,zw);
|
||||
m_el[3].setValue(wx,wy,wz,ww);
|
||||
}
|
||||
|
||||
inline void setIdentity()
|
||||
{
|
||||
m_el[0].setValue(1,0,0,0);
|
||||
m_el[1].setValue(0,1,0,0);
|
||||
m_el[2].setValue(0,0,1,0);
|
||||
m_el[3].setValue(0,0,0,1);
|
||||
}
|
||||
inline void setPureRotation(const btQuaternion& orn)
|
||||
{
|
||||
setIdentity();
|
||||
|
||||
btMatrix3x3 m3(orn);
|
||||
for (int i=0;i<3;i++)
|
||||
{
|
||||
for (int j=0;j<3;j++)
|
||||
{
|
||||
m_el[i][j] = m3[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void setPureScaling(const btVector3& scale)
|
||||
{
|
||||
m_el[0].setValue(scale[0],0,0,0);
|
||||
m_el[1].setValue(0,scale[1],0,0);
|
||||
m_el[2].setValue(0,0,scale[2],0);
|
||||
m_el[3].setValue(0,0,0,1);
|
||||
}
|
||||
|
||||
inline void setPureTranslation(const btVector3& pos)
|
||||
{
|
||||
m_el[0].setValue(1,0,0,pos[0]);
|
||||
m_el[1].setValue(0,1,0,pos[1]);
|
||||
m_el[2].setValue(0,0,1,pos[2]);
|
||||
m_el[3].setValue(0,0,0,1);
|
||||
|
||||
}
|
||||
SIMD_FORCE_INLINE const btVector4& operator[](int i) const
|
||||
{
|
||||
btFullAssert(0 <= i && i < 3);
|
||||
return m_el[i];
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar tdotx(const btVector4& v) const
|
||||
{
|
||||
return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z() + m_el[3].x()* v.w();
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar tdoty(const btVector4& v) const
|
||||
{
|
||||
return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z() + m_el[3].y() * v.w();
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar tdotz(const btVector4& v) const
|
||||
{
|
||||
return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z() + m_el[3].z() * v.w();
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar tdotw(const btVector4& v) const
|
||||
{
|
||||
return m_el[0].w() * v.x() + m_el[1].w() * v.y() + m_el[2].w() * v.z() + m_el[3].w() * v.w();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix4x4
|
||||
btMatrix4x4::operator*=(const btMatrix4x4& m)
|
||||
{
|
||||
setValue(
|
||||
m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),m.tdotw(m_el[0]),
|
||||
m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),m.tdotw(m_el[1]),
|
||||
m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]),m.tdotw(m_el[2]),
|
||||
m.tdotx(m_el[3]), m.tdoty(m_el[3]), m.tdotz(m_el[3]),m.tdotw(m_el[3]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline btScalar btDot4(const btVector4& v0, const btVector4& v1)
|
||||
{
|
||||
return v0.x()*v1.x()+v0.y()*v1.y()+v0.z()*v1.z()+v0.w()*v1.w();
|
||||
}
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btMatrix4x4& m, const btVector3& v1)
|
||||
{
|
||||
btVector4 v(v1[0],v1[1],v1[2],1);
|
||||
return btVector3(btDot4(m[0],v), btDot4(m[1],v), btDot4(m[2],v));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix4x4
|
||||
operator*(const btMatrix4x4& m1, btMatrix4x4& m2)
|
||||
{
|
||||
return btMatrix4x4(
|
||||
m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]),m2.tdotw(m1[0]),
|
||||
m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]),m2.tdotw(m1[1]),
|
||||
m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2]),m2.tdotw(m1[2]),
|
||||
m2.tdotx(m1[3]), m2.tdoty(m1[3]), m2.tdotz(m1[3]),m2.tdotw(m1[3]));
|
||||
}
|
||||
|
||||
|
||||
#endif //MATRIX4x4_H
|
198
data/duck.dae
Normal file
198
data/duck.dae
Normal file
File diff suppressed because one or more lines are too long
362
data/seymourplane_triangulate.dae
Normal file
362
data/seymourplane_triangulate.dae
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user