void ModelViewerRender::RenderStaticNormals() { if(m_pModelMF1==NULL) return ; const float NORMAL_LENGTH=0.02f; uint32 meshCount=m_pModelMF1->m_Header.m_iNumMeshes; for(uint32 i=0;i<meshCount;++i) { SGPMF1Mesh &mesh=m_pModelMF1->m_pLOD0Meshes[i]; uint32 vertexCount=m_pModelMF1->m_pLOD0Meshes[i].m_iNumVerts; SGPVertex_UPOS_VERTEXCOLOR* pVert=new SGPVertex_UPOS_VERTEXCOLOR[vertexCount*2]; for(uint32 j=0;j<vertexCount;++j) { SGPMF1Vertex& currVert=mesh.m_pVertex[j]; Vector4D startPos,endPos; startPos.Set(currVert.vPos[0],currVert.vPos[1],currVert.vPos[2]); startPos=startPos*m_pStaticModel->getModelMatrix(); endPos.Set(currVert.vPos[0]+currVert.vNormal[0]*NORMAL_LENGTH,currVert.vPos[1]+\ currVert.vNormal[1]*NORMAL_LENGTH,currVert.vPos[2]+currVert.vNormal[2]*NORMAL_LENGTH); endPos=endPos*m_pStaticModel->getModelMatrix(); SetVertexPos(pVert[2*j],startPos.x,startPos.y,startPos.z); SetVertexColor(pVert[2*j],1.0f,1.0f,1.0f,1.0f); SetVertexPos(pVert[2*j+1],endPos.x,endPos.y,endPos.z); SetVertexColor(pVert[2*j+1],1.0f,1.0f,1.0f,1.0f); } m_pRenderDevice->GetVertexCacheManager()->RenderLines(2*vertexCount,pVert,false); delete [] pVert; } }
void RenderHeightMap(unsigned char pHeightMap[]) /* This Renders The Height Map As Quads */ { int X = 0, Y = 0; /* Create Some Variables To Walk The Array With. */ int x, y, z; /* Create Some Variables For Readability */ if(!pHeightMap) return; /* Make Sure Our Height Data Is Valid */ if(bRender) /* What We Want To Render */ glBegin( GL_QUADS ); /* Render Polygons */ else glBegin( GL_LINES ); /* Render Lines Instead */ for ( X = 0; X < MAP_SIZE; X += STEP_SIZE ) for ( Y = 0; Y < MAP_SIZE; Y += STEP_SIZE ) { /* Get The (X, Y, Z) Value For The Bottom Left Vertex */ x = X; y = Height(pHeightMap, X, Y ); z = Y; /* Set The Color Value Of The Current Vertex */ SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); /* Send This Vertex To OpenGL To Be Rendered (Integer Points Are Faster) */ /* Get The (X, Y, Z) Value For The Top Left Vertex */ x = X; y = Height(pHeightMap, X, Y + STEP_SIZE ); z = Y + STEP_SIZE ; /* Set The Color Value Of The Current Vertex */ SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); /* Send This Vertex To OpenGL To Be Rendered */ /* Get The (X, Y, Z) Value For The Top Right Vertex */ x = X + STEP_SIZE; y = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); z = Y + STEP_SIZE ; /* Set The Color Value Of The Current Vertex */ SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); /* Send This Vertex To OpenGL To Be Rendered */ /* Get The (X, Y, Z) Value For The Bottom Right Vertex */ x = X + STEP_SIZE; y = Height(pHeightMap, X + STEP_SIZE, Y ); z = Y; /* Set The Color Value Of The Current Vertex */ SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); /* Send This Vertex To OpenGL To Be Rendered */ } glEnd(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); /*Reset The Color */ }
void RenderHeightMap(BYTE pHeightMap[]) // This Renders The Height Map As Quads { int X = 0, Y = 0; // Create Some Variables To Walk The Array With. int x, y, z; // Create Some Variables For Readability if(!pHeightMap) return; // Make Sure Our Height Data Is Valid glBegin( GL_QUADS ); // Render Polygons for ( X = 0; X < (MAP_SIZE-STEP_SIZE); X += STEP_SIZE ) for ( Y = 0; Y < (MAP_SIZE-STEP_SIZE); Y += STEP_SIZE ) { // Get The (X, Y, Z) Value For The Bottom Left Vertex x = X; y = Height(pHeightMap, X, Y ); z = Y; // Set The Color Value Of The Current Vertex SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered (Integer Points Are Faster) // Get The (X, Y, Z) Value For The Top Left Vertex x = X; y = Height(pHeightMap, X, Y + STEP_SIZE ); z = Y + STEP_SIZE ; // Set The Color Value Of The Current Vertex SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered // Get The (X, Y, Z) Value For The Top Right Vertex x = X + STEP_SIZE; y = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); z = Y + STEP_SIZE ; // Set The Color Value Of The Current Vertex SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered // Get The (X, Y, Z) Value For The Bottom Right Vertex x = X + STEP_SIZE; y = Height(pHeightMap, X + STEP_SIZE, Y ); z = Y; // Set The Color Value Of The Current Vertex SetVertexColor(pHeightMap, x, z); glVertex3i(x, y, z); // Send This Vertex To OpenGL To Be Rendered } glEnd(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Reset The Color }
// Masked lists only include quads. void RL_RenderMaskedList(rendlist_t *mrl) { int i; float tcleft, tcright, tctop, tcbottom; rendquad_t *cq; if (!mrl->numquads) return; // No quads to render, I'm afraid. // Curtex is used to keep track of the current texture. // Zero also denotes that no glBegin() has yet been called. curtex = 0; // Render quads. for (i = mrl->numquads-1; i >= 0; i--) // Render back to front. { cq = mrl->quads + i; // Calculate relative texture coordinates. tcright = (tcleft = cq->texoffx/cq->texw) + cq->u.q.len/cq->texw; tcbottom = (tctop = cq->texoffy/cq->texh) + (cq->top - cq->u.q.bottom)/cq->texh; // Is there a need to change the texture? if (curtex != cq->masktex) { if (curtex) glEnd(); // Finish with the old texture. glBindTexture(GL_TEXTURE_2D, curtex = cq->masktex); glBegin(GL_QUADS); // I love OpenGL. } // The vertices. SetVertexColor(cq->light, cq->dist[0], 1); glTexCoord2f(tcleft, tcbottom); glVertex3f(cq->v1[VX], cq->u.q.bottom, cq->v1[VY]); glTexCoord2f(tcleft, tctop); glVertex3f(cq->v1[VX], cq->top, cq->v1[VY]); SetVertexColor(cq->light, cq->dist[1], 1); glTexCoord2f(tcright, tctop); glVertex3f(cq->v2[VX], cq->top, cq->v2[VY]); glTexCoord2f(tcright, tcbottom); glVertex3f(cq->v2[VX], cq->u.q.bottom, cq->v2[VY]); } if (curtex) glEnd(); // If something was drawn, finish with it. }
void ModelViewerRender::InitGround() { int vertIndex=0; for( int Row=-13; Row<=13; Row++ ) { SetVertexPos(m_SurfaceVertex[vertIndex],Row*0.5f,0,-13*0.5f); SetVertexColor(m_SurfaceVertex[vertIndex],((Row==0)?0:0.6f),((Row==0)?0:0.6f),((Row==0)?0:0.6f),1.0f); vertIndex++; SetVertexPos(m_SurfaceVertex[vertIndex],Row*0.5f,0,13*0.5f); SetVertexColor(m_SurfaceVertex[vertIndex],((Row==0)?0:0.6f),((Row==0)?0:0.6f),((Row==0)?0:0.6f),1.0f); vertIndex++; } for( int Col=-13; Col<=13; Col++ ) { SetVertexPos(m_SurfaceVertex[vertIndex],-13*0.5f,0,Col*0.5f); SetVertexColor(m_SurfaceVertex[vertIndex],(Col==0)?0:0.6f,(Col==0)?0:0.6f,(Col==0)?0:0.6f,1.0f); vertIndex++; SetVertexPos(m_SurfaceVertex[vertIndex],13*0.5f,0,Col*0.5f); SetVertexColor(m_SurfaceVertex[vertIndex],(Col==0)?0:0.6f,(Col==0)?0:0.6f,(Col==0)?0:0.6f,1.0f); vertIndex++; } }
int SetVertexColors (tFaceProps *propsP) { if (SHOW_DYN_LIGHT) { // set material properties specific for certain textures here lightManager.SetMaterial (propsP->segNum, propsP->sideNum, -1); return 0; } memset (vertColors, 0, sizeof (vertColors)); if (gameStates.render.bAmbientColor) { int i, j = propsP->nVertices; for (i = 0; i < j; i++) SetVertexColor (propsP->vp [i], vertColors + i); } else memset (vertColors, 0, sizeof (vertColors)); return 1; }
void ModelViewerRender::CalTranlsatedVertex(SGPVertex_UPOS_VERTEXCOLOR &vertex,Matrix4x4* pBoneMatrix,int meshIndex,int vertexIndex,BOOL bOrigin) { const float NORMAL_LENGTH=0.02f; SGPMF1Mesh& mesh=m_pModelMF1->m_pLOD0Meshes[meshIndex]; SGPMF1BoneGroup& boneGroup=m_pModelMF1->m_pBoneGroup[mesh.m_pVertexBoneGroupID[vertexIndex]]; SGPMF1Vertex& vert=mesh.m_pVertex[vertexIndex]; Vector4D result,origin; if(bOrigin) origin.Set(vert.vPos[0],vert.vPos[1],vert.vPos[2]); else origin.Set(vert.vPos[0]+vert.vNormal[0]*NORMAL_LENGTH,vert.vPos[1]+vert.vNormal[1]*NORMAL_LENGTH,\ vert.vPos[2]+vert.vNormal[2]*NORMAL_LENGTH); uint8 totalWeight=0; if(boneGroup.BoneWeight.x!=0) { totalWeight+=boneGroup.BoneWeight.x; result=(origin*pBoneMatrix[boneGroup.BoneIndex.x])*(float)boneGroup.BoneWeight.x; } if(boneGroup.BoneWeight.y!=0) { totalWeight+=boneGroup.BoneWeight.y; result=result+(origin*pBoneMatrix[boneGroup.BoneIndex.y])*(float)boneGroup.BoneWeight.y; } if(boneGroup.BoneWeight.z!=0) { totalWeight+=boneGroup.BoneWeight.z; result=result+(origin*pBoneMatrix[boneGroup.BoneIndex.z])*(float)boneGroup.BoneWeight.z; } if(boneGroup.BoneWeight.w!=0) { totalWeight+=boneGroup.BoneWeight.w; result=result+(origin*pBoneMatrix[boneGroup.BoneIndex.w])*(float)boneGroup.BoneWeight.w; } result*=1/(float)totalWeight; SetVertexPos(vertex,result.x,result.y,result.z); SetVertexColor(vertex,1.0f,1.0f,1.0f,1.0f); }
void ModelViewerRender::RenderCoordinateAxis() { Matrix4x4 matView, matProj, matInvViewProj; Vector4D OrigTo; // proj position Vector4D vAxisOrig( -0.75f, -0.75f, 0.1f); m_pRenderDevice->getViewMatrix(matView); m_pRenderDevice->getProjMatrix(matProj); // Inverse view*proj to get "proj->world" transform matInvViewProj.InverseOf( matView*matProj ); // move the obj to leftbottom of camera then transfer to world coordinate Vector4D Orig = vAxisOrig * matInvViewProj; Orig.x /= Orig.w; Orig.y /= Orig.w; Orig.z /= Orig.w; Orig.w = 1; // draw the lines stand for coordinate const float LINE_LENGTH = 0.002f; // RED X OrigTo = Orig + Vector4D(LINE_LENGTH,0,0); SetVertexPos(m_AxisVertex[0],Orig.x,Orig.y,Orig.z); SetVertexColor(m_AxisVertex[0],1.0f,0.0f,0.0f,1.0f); SetVertexPos(m_AxisVertex[1],OrigTo.x,OrigTo.y,OrigTo.z); SetVertexColor(m_AxisVertex[1],1.0f,0.0f,0.0f,1.0f); // GREEN Y OrigTo = Orig + Vector4D(0,LINE_LENGTH,0); SetVertexPos(m_AxisVertex[2],Orig.x,Orig.y,Orig.z); SetVertexColor(m_AxisVertex[2],0.0f,1.0f,0.0f,1.0f); SetVertexPos(m_AxisVertex[3],OrigTo.x,OrigTo.y,OrigTo.z); SetVertexColor(m_AxisVertex[3],0.0f,1.0f,0.0f,1.0f); // BLUE Z OrigTo = Orig + Vector4D(0,0,LINE_LENGTH); SetVertexPos(m_AxisVertex[4],Orig.x,Orig.y,Orig.z); SetVertexColor(m_AxisVertex[4],0.0f,0.0f,1.0f,1.0f); SetVertexPos(m_AxisVertex[5],OrigTo.x,OrigTo.y,OrigTo.z); SetVertexColor(m_AxisVertex[5],0.0f,0.0f,1.0f,1.0f); m_pRenderDevice->GetVertexCacheManager()->RenderLines(6,m_AxisVertex,false); }
// This is only for solid, non-masked primitives. void RL_RenderList(rendlist_t *rl) { int i; float tcleft, tcright, tctop, tcbottom; rendquad_t *cq; if (!rl->numquads) return; // The list is empty. // Bind the right texture. glBindTexture(GL_TEXTURE_2D, curtex = rl->tex); // Check what kind of primitives there are on the list. // There can only be one kind on each list. if (rl->quads->flags & RQF_FLAT) // Check the first primitive. { // There's only triangles here, I see. glBegin(GL_TRIANGLES); for (i = 0; i < rl->numquads; i++) { cq = rl->quads + i; if (cq->flags & RQF_MISSING_WALL) { // This triangle is REALLY a quad that originally had no // texture. We have to render it as two triangles. tcright = (tcleft = 0) + cq->u.q.len/cq->texw; tcbottom = (tctop = 0) + (cq->top - cq->u.q.bottom)/cq->texh; SetVertexColor(cq->light, cq->dist[0], 1); glTexCoord2f(tcleft, tctop); glVertex3f(cq->v1[VX], cq->top, cq->v1[VY]); SetVertexColor(cq->light, cq->dist[1], 1); glTexCoord2f(tcright, tctop); glVertex3f(cq->v2[VX], cq->top, cq->v2[VY]); glTexCoord2f(tcright, tcbottom); glVertex3f(cq->v2[VX], cq->u.q.bottom, cq->v2[VY]); // The other triangle. glTexCoord2f(tcright, tcbottom); glVertex3f(cq->v2[VX], cq->u.q.bottom, cq->v2[VY]); SetVertexColor(cq->light, cq->dist[0], 1); glTexCoord2f(tcleft, tcbottom); glVertex3f(cq->v1[VX], cq->u.q.bottom, cq->v1[VY]); glTexCoord2f(tcleft, tctop); glVertex3f(cq->v1[VX], cq->top, cq->v1[VY]); continue; } // The vertices. SetVertexColor(cq->light, cq->dist[0], 1); glTexCoord2f((cq->v1[VX] + cq->texoffx)/cq->texw, (cq->v1[VY] + cq->texoffy)/cq->texh); glVertex3f(cq->v1[VX], cq->top, cq->v1[VY]); SetVertexColor(cq->light, cq->dist[1], 1); glTexCoord2f((cq->v2[VX] + cq->texoffx)/cq->texw, (cq->v2[VY] + cq->texoffy)/cq->texh); glVertex3f(cq->v2[VX], cq->top, cq->v2[VY]); SetVertexColor(cq->light, cq->dist[2], 1); glTexCoord2f((cq->u.v3[VX] + cq->texoffx)/cq->texw, (cq->u.v3[VY] + cq->texoffy)/cq->texh); glVertex3f(cq->u.v3[VX], cq->top, cq->u.v3[VY]); } glEnd(); } else { // Render quads. glBegin(GL_QUADS); for (i = 0; i < rl->numquads; i++) { cq = rl->quads + i; // Calculate relative texture coordinates. tcright = (tcleft = cq->texoffx/(float)cq->texw) + cq->u.q.len/cq->texw; tcbottom = (tctop = cq->texoffy/cq->texh) + (cq->top - cq->u.q.bottom)/cq->texh; // The vertices. SetVertexColor(cq->light, cq->dist[0], 1); glTexCoord2f(tcleft, tcbottom); glVertex3f(cq->v1[VX], cq->u.q.bottom, cq->v1[VY]); glTexCoord2f(tcleft, tctop); glVertex3f(cq->v1[VX], cq->top, cq->v1[VY]); SetVertexColor(cq->light, cq->dist[1], 1); glTexCoord2f(tcright, tctop); glVertex3f(cq->v2[VX], cq->top, cq->v2[VY]); glTexCoord2f(tcright, tcbottom); glVertex3f(cq->v2[VX], cq->u.q.bottom, cq->v2[VY]); } glEnd(); } }
void CBSPMapData_LW::SetFace(vector<CMapFace>* pvecFace, list<LWO2_Layer>::iterator thislayer) { int i; WORD j; DWORD pnt_index; MAPVERTEX vDest; SPlane plane; LWO2_Object& lwobject = this->m_LWO2Object; LWO2_TextureUVMap* pTexuvmap = NULL; LWO2_VertexColorMap* pVertexColorMap = NULL; int iSurfaceIndex; int offset = pvecFace->size(); // caution : this is a temporary solution. this will not work when multiple PNTS chunks exist // in a single layer. LWO2_TextureUVMap *pLightmapTextureUVMap = lwobject.FindTextureUVMapByName( "TUV_Lightmap", *thislayer ); vector<LWO2_Face>& rvecPolygon = thislayer->GetFace(); int iNumFaces = rvecPolygon.size(); for(i=0; i<iNumFaces; i++) // How many faces in the layer { LWO2_Face& rSrcFace = rvecPolygon[i]; if( rSrcFace.GetNumPoints() <= 2 ) continue; CMapFace new_face; // Find the surface mapped on this face LWO2_Surface& rSurf = lwobject.FindSurfaceFromTAG( rSrcFace.GetSurfaceIndex() ); iSurfaceIndex = lwobject.GetSurfaceIndexFromSurfaceTAG( rSrcFace.GetSurfaceIndex() ); strcpy( new_face.m_acSurfaceName, rSurf.GetName().c_str() ); // set material index new_face.m_iSurfaceMaterialIndex = GetMaterialIndex( rSurf ); // if the surface name contains "_NoClip" if( strstr(rSurf.GetName().c_str(),"_NoClip") ) new_face.RaiseTypeFlag(CMapFace::TYPE_NOCLIP); // no collision detection against this face else new_face.ClearTypeFlag(CMapFace::TYPE_NOCLIP); // usual case if( strstr(rSurf.GetName().c_str(),"_Invisible") ) //if the surface name contains "_Invisible" new_face.RaiseTypeFlag(CMapFace::TYPE_INVISIBLE); // this face is not rendered else new_face.ClearTypeFlag(CMapFace::TYPE_INVISIBLE); // usual case // find the image mapped on this face and get its index new_face.m_sTextureID = iSurfaceIndex; // The value of TextureID is given as the order of the still image // in vector<m_clipstill> // If a still image is the first element in vector<m_clipstill>, // the TextureID of its owner face is 0 // The image index of CLIP chunk in LWO2 file starts from 1. Therefore, if a surface doesn't // have any image, imagetag of the surface should be 0. << Is this right? // And the 'm_sTextureID' remains -1 // find the texture uvmap of this face pTexuvmap = lwobject.FindTextureUVMapFromSurface(rSurf, ID_COLR, *thislayer); // find the vertex color map applied to this face pVertexColorMap= lwobject.FindVertexColorMapFromSurface(rSurf, *thislayer); int iNumPoints = rSrcFace.GetNumPoints(); for(j=0; j<iNumPoints ;j++) // the number of points in this face { memset(&vDest, 0, sizeof(MAPVERTEX)); vDest.color = 0xFFFFFFFF; //default vertex color: white and opaque pnt_index = rSrcFace.GetVertexIndex()[j]; // the index to a point in the PNTS chunk vDest.vPosition = thislayer->GetVertex().at( pnt_index ); // set texture-uv to the vertex // search uv map (VMAP chunk) until the corresponding uv-point is found if( pTexuvmap ) // if (pTexuvmap == NULL), we have no uv points for this face { if( !thislayer->GetUV( vDest.vTex0.u, vDest.vTex0.v, pnt_index, pTexuvmap ) ) { vDest.vTex0.u = 32767; vDest.vTex0.v = 32767; } } new_face.m_sLightMapID = -1; /* if( pLightmapTextureUVMap ) { if( !thislayer->GetUV( vDest.vTex1.u, vDest.vTex1.v, pnt_index, pLightmapTextureUVMap ) ) { vDest.vTex1.u = -1; vDest.vTex1.v = -1; } else new_face.m_sLightMapID = 0; // TODO: support for multiple lightmap textures }*/ if( pVertexColorMap ) SetVertexColor( vDest, pnt_index, (DWORD)i, pVertexColorMap ); if( rSurf.GetMaxSmoothingAngle() < 3.141592f / 2.0f * 89.9f / 90.0f ) vDest.vNormal = thislayer->GetInterpolatedNormal( rSrcFace, pnt_index ); // smooth shadeing else vDest.vNormal = rSrcFace.GetFaceNormal(); // flat shading //========== normal direction check (visual debugging) ============================================= // vDest.color = D3DCOLOR_XRGB( abs((int)(vDest.vNormal.x * 250.0f)), // abs((int)(vDest.vNormal.y * 250.0f)), // abs((int)(vDest.vNormal.z * 250.0f)) ); //========== normal direction check (visual debugging) ============================================= new_face.AddMAPVERTEX(vDest); } new_face.m_sNode = 0; new_face.m_bFlag = false; if( strstr(rSurf.GetName().c_str(),"_LightSource") ) { // mark as a light source new_face.RaiseTypeFlag( CMapFace::TYPE_LIGHTSOURCE ); new_face.RaiseTypeFlag( CMapFace::TYPE_NOCLIP ); // light source faces are not used for collision detection - actually, this is not a good solution } //========== normal direction check ============================================= // for(j=0; j<new_face.GetNumVertices()-1; j++) // { // if( 0.001f < D3DXVec3LengthSq( &(new_face.GetMapVertex(j).vNormal - new_face.GetMapVertex(j+1).vNormal) ) ) // int iSmoothShadingPolygon = 1; // } //========== normal direction check ============================================= pvecFace->push_back( new_face ); } }
void ModelViewerRender::RenderBones() { if(m_pModelMF1==NULL) return ; // const float boneOffset[3]={0.05f,0.05f,0.05f}; const float boneOffset[3]={0.0f,0.0f,0.0f}; uint32 nBoneCount=m_pModelMF1->m_iNumBones; SGPMF1Bone* pBones=m_pModelMF1->m_pBones; float* pBoneMatrixs=m_pDynamicModel->getBonesMatrix(); SGPVertex_UPOS_VERTEXCOLOR vertex[2]; SetVertexColor(vertex[0],1.0f,1.0f,1.0f,1.0f); SetVertexColor(vertex[1],1.0f,1.0f,1.0f,1.0f); for(uint32 i=0;i<nBoneCount;++i) { uint32 childCount=pBones[i].m_iNumChildId; if(childCount!=0) { Matrix4x4 matFrame0; matFrame0.InverseOf(pBones[i].m_matFrame0Inv); Matrix4x4 matAnimation; matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*i]; matAnimation._21=pBoneMatrixs[12*i+1]; matAnimation._31=pBoneMatrixs[12*i+2]; matAnimation._41=pBoneMatrixs[12*i+3]; matAnimation._12=pBoneMatrixs[12*i+4]; matAnimation._22=pBoneMatrixs[12*i+5]; matAnimation._32=pBoneMatrixs[12*i+6]; matAnimation._42=pBoneMatrixs[12*i+7]; matAnimation._13=pBoneMatrixs[12*i+8]; matAnimation._23=pBoneMatrixs[12*i+9]; matAnimation._33=pBoneMatrixs[12*i+10]; matAnimation._43=pBoneMatrixs[12*i+11]; Matrix4x4 matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); // SetVertexPos(vertex[0],matOrigin._41+0.05f,matOrigin._42+0.05f,matOrigin._43+0.05f); SetVertexPos(vertex[0],matOrigin._41+boneOffset[0],matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]); if(pBones[i].m_sParentID==0xFFFF) { AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength()/150.0f; m_pRenderDevice->GetVertexCacheManager()->RenderDetailSphere(Vector3D(matOrigin._41+boneOffset[0],\ matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]),length,5,5,Colour(255,255,255)); } for(uint32 j=0;j<childCount;++j) { uint16 index=pBones[i].m_ChildIds[j]; matFrame0.InverseOf(pBones[index].m_matFrame0Inv); matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*index]; matAnimation._21=pBoneMatrixs[12*index+1]; matAnimation._31=pBoneMatrixs[12*index+2]; matAnimation._41=pBoneMatrixs[12*index+3]; matAnimation._12=pBoneMatrixs[12*index+4]; matAnimation._22=pBoneMatrixs[12*index+5]; matAnimation._32=pBoneMatrixs[12*index+6]; matAnimation._42=pBoneMatrixs[12*index+7]; matAnimation._13=pBoneMatrixs[12*index+8]; matAnimation._23=pBoneMatrixs[12*index+9]; matAnimation._33=pBoneMatrixs[12*index+10]; matAnimation._43=pBoneMatrixs[12*index+11]; matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); SetVertexPos(vertex[1],matOrigin._41+boneOffset[0],matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]); m_pRenderDevice->GetVertexCacheManager()->RenderLines(2,vertex,false); } } else if(pBones[i].m_sParentID==0xFFFF)//the bone don't have children { Matrix4x4 matFrame0; matFrame0.InverseOf(pBones[i].m_matFrame0Inv); Matrix4x4 matAnimation; matAnimation.Identity(); matAnimation._11=pBoneMatrixs[12*i]; matAnimation._21=pBoneMatrixs[12*i+1]; matAnimation._31=pBoneMatrixs[12*i+2]; matAnimation._41=pBoneMatrixs[12*i+3]; matAnimation._12=pBoneMatrixs[12*i+4]; matAnimation._22=pBoneMatrixs[12*i+5]; matAnimation._32=pBoneMatrixs[12*i+6]; matAnimation._42=pBoneMatrixs[12*i+7]; matAnimation._13=pBoneMatrixs[12*i+8]; matAnimation._23=pBoneMatrixs[12*i+9]; matAnimation._33=pBoneMatrixs[12*i+10]; matAnimation._43=pBoneMatrixs[12*i+11]; Matrix4x4 matOrigin=matFrame0*matAnimation*m_pDynamicModel->getModelMatrix(); AABBox aabox=m_pModelMF1->m_MeshAABBox; float length=(aabox.vcMax-aabox.vcMin).GetLength()/150.0f; m_pRenderDevice->GetVertexCacheManager()->RenderDetailSphere(Vector3D(matOrigin._41+boneOffset[0],\ matOrigin._42+boneOffset[1],matOrigin._43+boneOffset[2]),length,5,5,Colour(255,255,255)); } } }