void CModelSurface::Transform( const CMat4 &matrix,const CMat4 &itMatrix ){ for( vector<CVertex>::iterator it=_vertices.begin();it!=_vertices.end();++it ){ CVertex &v=*it; v.position=matrix * v.position; v.normal=(itMatrix * CVec4( v.normal,0.0f ) ).xyz().Normalize(); v.tangent=CVec4( (itMatrix * CVec4( v.tangent.xyz(),0.0f ) ).xyz().Normalize(),v.tangent.w ); } }
void CModelSurface::UpdateTangents(){ vector<CVec3> stangs( _vertices.size() ); vector<CVec3> ttangs( _vertices.size() ); for( vector<CTriangle>::iterator it=_triangles.begin();it!=_triangles.end();++it ){ const CTriangle &tri=*it; int i0=tri.vertices[0]; int i1=tri.vertices[1]; int i2=tri.vertices[2]; const CVec3 &v0=_vertices[i0].position; const CVec3 &v1=_vertices[i1].position; const CVec3 &v2=_vertices[i2].position; const CVec2 &c0=_vertices[i0].texcoords[0]; const CVec2 &c1=_vertices[i1].texcoords[0]; const CVec2 &c2=_vertices[i2].texcoords[0]; CVec3 side0=v0-v1,side1=v2-v1; float deltas0=c0.x-c1.x,deltas1=c2.x-c1.x; float deltat0=c0.y-c1.y,deltat1=c2.y-c1.y; CVec3 stang=( (side0 * deltat1)-(side1 * deltat0) ).Normalize(); CVec3 ttang=( (side0 * deltas1)-(side1 * deltas0) ).Normalize(); stangs[i0]+=stang; ttangs[i0]+=ttang; stangs[i1]+=stang; ttangs[i1]+=ttang; stangs[i2]+=stang; ttangs[i2]+=ttang; } for( int i=0;i<_vertices.size();++i ){ const CVec3 &n=_vertices[i].normal; const CVec3 &t=stangs[i]; CVec3 tang=( t-n*n.Dot(t) ).Normalize(); float w=n.Cross(t).Dot( ttangs[i] )>0 ? 1 : -1; _vertices[i].tangent=CVec4( tang,w ); } }
static CModel *cmodel( const aiMesh *mesh ){ CModel *model=new CModel; const CVec3 scale( .035,.035,.035 ); aiVector3D *mv=mesh->mVertices; aiVector3D *mn=mesh->mNormals; aiVector3D *mt=mesh->mTangents; aiVector3D *mb=mesh->mBitangents; aiVector3D *mc=mesh->mTextureCoords[0]; for( int i=0;i<mesh->mNumVertices;++i ){ float tw=1.0; if( mn && mt && mb ){ CVec3 norm=*(CVec3*)mn; CVec3 tang=*(CVec3*)mt; CVec3 bitang=*(CVec3*)mb; if( norm.Dot( tang.Cross(bitang) )<0.0f ) tw=-1.0f; } CVertex v; v.position=scale * *(CVec3*)mv++; if( mn ) v.normal=*(CVec3*)mn++; if( mt ) v.tangent=CVec4( *(CVec3*)mt++,tw ); if( mc ) v.texcoords[0]=*(CVec2*)mc++; model->AddVertex( v ); } aiFace *face=mesh->mFaces; for( int i=0;i<mesh->mNumFaces;++i ){ model->AddTriangle( face->mIndices[0],face->mIndices[1],face->mIndices[2] ); ++face; } // model->UpdateNormals(); model->UpdateTangents(); return model; }
CVec4 CVec4::operator - (const CVec4& rhs) const { glm::vec4 ret = m_data - rhs.m_data; return CVec4(ret.x, ret.y, ret.z, ret.w); }
CVec4 CVec4::operator * (float rhs) const { glm::vec4 ret = m_data * rhs; return CVec4(ret.x, ret.y, ret.z, ret.w); }
CVec4 CVec4::operator * (const CMat4& mat) const { glm::vec4 ret = mat.m_data * m_data; return CVec4(ret.x, ret.y, ret.z, ret.w); }