Implemented KRNode::getInverseModelMatrix

Implemented KRNode::rayCast
Implemented KRNode::lineCast
Fixed bug in KRCollider::rayCast

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40193
This commit is contained in:
kearwood
2012-12-15 01:39:32 +00:00
parent 834ad916e4
commit eb7f07d654
7 changed files with 63 additions and 2 deletions

View File

@@ -73,3 +73,30 @@ KRAABB KRCollider::getBounds() {
} }
} }
bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
if(m_models.size()) {
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1);
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode());
return true;
}
}
return false;
}
bool KRCollider::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
if(m_models.size()) {
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
KRVector3 v1_model_space = v0_model_space + KRMat4::DotNoTranslate(getModelMatrix(), KRVector3::Normalize(v1 - v0));
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode());
return true;
}
}
return false;
}

View File

@@ -55,6 +55,9 @@ public:
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual KRAABB getBounds(); virtual KRAABB getBounds();
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
private: private:
std::vector<KRModel *> m_models; std::vector<KRModel *> m_models;
std::string m_model_name; std::string m_model_name;

View File

@@ -293,6 +293,16 @@ KRVector3 KRMat4::Dot(const KRMat4 &m, const KRVector3 &v) {
); );
} }
// Dot product without including translation; useful for transforming normals and tangents
KRVector3 DotNoTranslate(const KRMat4 &m, const KRVector3 &v)
{
return KRVector3(
v.x * (float)m[0*4 + 0] + v.y * (float)m[1*4 + 0] + v.z * (float)m[2*4 + 0],
v.x * (float)m[0*4 + 1] + v.y * (float)m[1*4 + 1] + v.z * (float)m[2*4 + 1],
v.x * (float)m[0*4 + 2] + v.y * (float)m[1*4 + 2] + v.z * (float)m[2*4 + 2]
);
}
/* Dot Product, returning w component as if it were a KRVector4 (This will be deprecated once KRVector4 is implemented instead*/ /* Dot Product, returning w component as if it were a KRVector4 (This will be deprecated once KRVector4 is implemented instead*/
float KRMat4::DotW(const KRMat4 &m, const KRVector3 &v) { float KRMat4::DotW(const KRMat4 &m, const KRVector3 &v) {
return v.x * (float)m[0*4 + 3] + v.y * (float)m[1*4 + 3] + v.z * (float)m[2*4 + 3] + (float)m[3*4 + 3]; return v.x * (float)m[0*4 + 3] + v.y * (float)m[1*4 + 3] + v.z * (float)m[2*4 + 3] + (float)m[3*4 + 3];

View File

@@ -104,6 +104,7 @@ public:
bool invert(); bool invert();
void transpose(); void transpose();
static KRVector3 DotNoTranslate(const KRMat4 &m, const KRVector3 &v); // Dot product without including translation; useful for transforming normals and tangents
static KRMat4 Invert(const KRMat4 &m); static KRMat4 Invert(const KRMat4 &m);
static KRMat4 Transpose(const KRMat4 &m); static KRMat4 Transpose(const KRMat4 &m);
static KRVector3 Dot(const KRMat4 &m, const KRVector3 &v); static KRVector3 Dot(const KRMat4 &m, const KRVector3 &v);

View File

@@ -774,8 +774,14 @@ bool KRModel::rayCast(const KRVector3 &line_v0, const KRVector3 &line_v1, const
// Update the hitinfo object if this hit is closer than the prior hit // Update the hitinfo object if this hit is closer than the prior hit
// Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2
KRVector3 distances = KRVector3::Normalize(KRVector3((tri_v0 - hit_point).magnitude(), (tri_v1 - hit_point).magnitude(), (tri_v2 - hit_point).magnitude())); float distance_v0 = (tri_v0 - hit_point).magnitude();
KRVector3 normal = tri_n0 * (1.0 - distances[0]) + tri_n1 * (1.0 - distances[1]) + tri_n2 * (1.0 - distances[3]); float distance_v1 = (tri_v1 - hit_point).magnitude();
float distance_v2 = (tri_v2 - hit_point).magnitude();
float distance_total = distance_v0 + distance_v1 + distance_v2;
distance_v0 /= distance_total;
distance_v1 /= distance_total;
distance_v2 /= distance_total;
KRVector3 normal = tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2);
hitinfo = KRHitInfo(hit_point, KRVector3()); hitinfo = KRHitInfo(hit_point, KRVector3());
} }

View File

@@ -33,6 +33,7 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_pScene = &scene; m_pScene = &scene;
getScene().notify_sceneGraphCreate(this); getScene().notify_sceneGraphCreate(this);
m_modelMatrixValid = false; m_modelMatrixValid = false;
m_inverseModelMatrixValid = false;
m_bindPoseMatrixValid = false; m_bindPoseMatrixValid = false;
m_inverseBindPoseMatrixValid = false; m_inverseBindPoseMatrixValid = false;
m_modelMatrix = KRMat4(); m_modelMatrix = KRMat4();
@@ -98,6 +99,7 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) {
m_bindPoseMatrixValid = false; m_bindPoseMatrixValid = false;
m_inverseBindPoseMatrixValid = false; m_inverseBindPoseMatrixValid = false;
m_modelMatrixValid = false; m_modelMatrixValid = false;
m_inverseModelMatrixValid = false;
for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) {
KRNode *child_node = KRNode::LoadXML(getScene(), child_element); KRNode *child_node = KRNode::LoadXML(getScene(), child_element);
@@ -237,6 +239,7 @@ KRAABB KRNode::getBounds() {
void KRNode::invalidateModelMatrix() void KRNode::invalidateModelMatrix()
{ {
m_modelMatrixValid = false; m_modelMatrixValid = false;
m_inverseModelMatrixValid = false;
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
KRNode *child = (*itr); KRNode *child = (*itr);
child->invalidateModelMatrix(); child->invalidateModelMatrix();
@@ -275,6 +278,14 @@ const KRMat4 &KRNode::getModelMatrix()
return m_modelMatrix; return m_modelMatrix;
} }
const KRMat4 &KRNode::getInverseModelMatrix()
{
if(!m_inverseModelMatrixValid) {
m_inverseModelMatrix = KRMat4::Invert(getModelMatrix());
}
return m_inverseModelMatrix;
}
const KRMat4 &KRNode::getBindPoseMatrix() const KRMat4 &KRNode::getBindPoseMatrix()
{ {
if(!m_bindPoseMatrixValid) { if(!m_bindPoseMatrixValid) {

View File

@@ -73,6 +73,7 @@ public:
virtual KRAABB getBounds(); virtual KRAABB getBounds();
const KRMat4 &getModelMatrix(); const KRMat4 &getModelMatrix();
const KRMat4 &getInverseModelMatrix();
const KRMat4 &getBindPoseMatrix(); const KRMat4 &getBindPoseMatrix();
const KRMat4 &getInverseBindPoseMatrix(); const KRMat4 &getInverseBindPoseMatrix();
@@ -114,9 +115,11 @@ private:
void invalidateModelMatrix(); void invalidateModelMatrix();
void invalidateBindPoseMatrix(); void invalidateBindPoseMatrix();
KRMat4 m_modelMatrix; KRMat4 m_modelMatrix;
KRMat4 m_inverseModelMatrix;
KRMat4 m_bindPoseMatrix; KRMat4 m_bindPoseMatrix;
KRMat4 m_inverseBindPoseMatrix; KRMat4 m_inverseBindPoseMatrix;
bool m_modelMatrixValid; bool m_modelMatrixValid;
bool m_inverseModelMatrixValid;
bool m_bindPoseMatrixValid; bool m_bindPoseMatrixValid;
bool m_inverseBindPoseMatrixValid; bool m_inverseBindPoseMatrixValid;