Fix physics of instanced nodes

This commit is contained in:
Marianne Gagnon
2014-08-09 21:22:12 -04:00
parent e6b558262b
commit b2e08c94a7
3 changed files with 111 additions and 48 deletions

View File

@@ -119,6 +119,27 @@ void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const cor
instance_pos.push_back(scale.Z);
}
core::matrix4 STKInstancedSceneNode::getInstanceTransform(int id)
{
core::matrix4 mat;
int offset = id * 9;
mat.setTranslation(core::vector3df(
instance_pos[offset],
instance_pos[offset + 1],
instance_pos[offset + 2]));
mat.setRotationDegrees(core::vector3df(
instance_pos[offset + 3],
instance_pos[offset + 4],
instance_pos[offset + 5]));
mat.setScale(core::vector3df(
instance_pos[offset + 6],
instance_pos[offset + 7],
instance_pos[offset + 8]));
return mat;
}
static void drawFSPMDefault(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();

View File

@@ -28,6 +28,10 @@ public:
virtual void render();
void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale);
int getInstanceCount() const { return instance_pos.size() / 9; }
core::matrix4 getInstanceTransform(int id);
void instanceGrab() { m_ref_count++; }
void instanceDrop()
{

View File

@@ -37,6 +37,7 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
@@ -729,10 +730,25 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
"This track contains an empty LOD group.");
return;
}
node->updateAbsolutePosition();
}
node->updateAbsolutePosition();
std::vector<core::matrix4> matrices;
STKInstancedSceneNode* instancing_node = dynamic_cast<STKInstancedSceneNode*>(node);
if (instancing_node != NULL)
{
int count = instancing_node->getInstanceCount();
for (int i = 0; i < count; i++)
{
matrices.push_back(instancing_node->getInstanceTransform(i));
}
}
else
{
matrices.push_back(node->getAbsoluteTransformation());
}
const core::vector3df &pos = node->getAbsolutePosition();
@@ -774,14 +790,15 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
return;
} // switch node->getType()
core::matrix4 mat;
mat.setRotationDegrees(hpr);
mat.setTranslation(pos);
core::matrix4 mat_scale;
// Note that we can't simply call mat.setScale, since this would
// overwrite the elements on the diagonal, making any rotation incorrect.
mat_scale.setScale(scale);
mat *= mat_scale;
//core::matrix4 mat;
//mat.setRotationDegrees(hpr);
//mat.setTranslation(pos);
//core::matrix4 mat_scale;
//// Note that we can't simply call mat.setScale, since this would
//// overwrite the elements on the diagonal, making any rotation incorrect.
//mat_scale.setScale(scale);
//mat *= mat_scale;
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
@@ -835,59 +852,80 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
if (mb->getVertexType() == video::EVT_STANDARD)
{
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
{
for(unsigned int k=0; k<3; k++)
for (unsigned int j = 0; j < mb->getIndexCount(); j += 3)
{
int indx=mbIndices[j+k];
core::vector3df v = mbVertices[indx].Pos;
mat.transformVect(v);
vertices[k]=v;
normals[k]=mbVertices[indx].Normal;
} // for k
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material );
} // for j
for (unsigned int k = 0; k < 3; k++)
{
int indx = mbIndices[j + k];
core::vector3df v = mbVertices[indx].Pos;
matrices[matrix_index].transformVect(v);
vertices[k] = v;
normals[k] = mbVertices[indx].Normal;
} // for k
if (tmesh)
{
tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material);
}
} // for j
} // for matrix_index
}
else if (mb->getVertexType() == video::EVT_2TCOORDS)
{
irr::video::S3DVertex2TCoords* mbVertices = (video::S3DVertex2TCoords*)mb->getVertices();
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
{
for(unsigned int k=0; k<3; k++)
for (unsigned int j = 0; j < mb->getIndexCount(); j += 3)
{
int indx=mbIndices[j+k];
core::vector3df v = mbVertices[indx].Pos;
mat.transformVect(v);
vertices[k]=v;
normals[k]=mbVertices[indx].Normal;
} // for k
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material );
} // for j
for (unsigned int k = 0; k < 3; k++)
{
int indx = mbIndices[j + k];
core::vector3df v = mbVertices[indx].Pos;
matrices[matrix_index].transformVect(v);
vertices[k] = v;
normals[k] = mbVertices[indx].Normal;
} // for k
if (tmesh)
{
tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material);
}
} // for j
} // for matrix_index
}
else if (mb->getVertexType() == video::EVT_TANGENTS)
{
irr::video::S3DVertexTangents* mbVertices = (video::S3DVertexTangents*)mb->getVertices();
for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
{
for(unsigned int k=0; k<3; k++)
for (unsigned int j = 0; j < mb->getIndexCount(); j += 3)
{
int indx=mbIndices[j+k];
core::vector3df v = mbVertices[indx].Pos;
mat.transformVect(v);
vertices[k]=v;
normals[k]=mbVertices[indx].Normal;
} // for k
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material );
} // for j
for (unsigned int k = 0; k < 3; k++)
{
int indx = mbIndices[j + k];
core::vector3df v = mbVertices[indx].Pos;
matrices[matrix_index].transformVect(v);
vertices[k] = v;
normals[k] = mbVertices[indx].Normal;
} // for k
if (tmesh)
{
tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], normals[0],
normals[1], normals[2],
material);
}
} // for j
} // for matrix_index
}
} // for i<getMeshBufferCount