#include "model.h" void CMs3D::Load(char* name) { FILE* mdlFile; mdlFile = fopen ( name , "rb" ); CMs3D_Header header; fread (&header, sizeof(CMs3D_Header), 1, mdlFile); fread(&numVerts, sizeof(unsigned short), 1, mdlFile); verts = new CMs3D_Vertex[numVerts]; fread(verts, sizeof(CMs3D_Vertex), numVerts, mdlFile); fread(&numFaces, sizeof(unsigned short), 1, mdlFile); faces = new CMs3D_Face[numFaces]; fread(faces, sizeof(CMs3D_Face), numFaces, mdlFile); fread(&numGroups, sizeof(unsigned short), 1, mdlFile); groups = new CMs3D_Group[numGroups]; for( int i = 0; i < numGroups; i++ ) { fread( &groups[i].flags, sizeof( unsigned char ), 1, mdlFile ); fread( groups[i].name, sizeof( char ), 32, mdlFile ); fread( &groups[i].numtriangles,sizeof( unsigned short ), 1, mdlFile ); groups[i].triangleIndices = new unsigned short[ groups[i].numtriangles ]; fread( groups[i].triangleIndices, sizeof( unsigned short ), groups[i].numtriangles, mdlFile ); fread( &groups[i].materialIndex, sizeof( char ), 1, mdlFile ); } fread( &numMaterials, sizeof( unsigned short ), 1, mdlFile ); materials = new CMs3D_Material[ numMaterials ]; for( int i = 0; i < numMaterials; i++ ) { fread( materials[i].name, sizeof( char ), 32, mdlFile ); fread( materials[i].ambient, sizeof( float ), 4, mdlFile ); fread( materials[i].diffuse, sizeof( float ), 4, mdlFile ); fread( materials[i].specular, sizeof( float ), 4, mdlFile ); fread( materials[i].emissive, sizeof( float ), 4, mdlFile ); fread( &materials[i].shininess, sizeof( float ), 1, mdlFile ); fread( &materials[i].transparency, sizeof( float ), 1, mdlFile ); fread( &materials[i].mode, sizeof( char ), 1, mdlFile ); fread( materials[i].texture, sizeof( char ), 128, mdlFile ); fread( materials[i].alphamap, sizeof(char), 128, mdlFile ); // materials[i].Texture.LoadTGA(materials[i].texture); // logWrite("UR MOM1"); materials[i].Texture.LoadTGA(materials[i].texture); // logWrite("UR MOM2"); glGenTextures(1, &materials[i].Texture.ID); // logWrite("UR MOM3"); glBindTexture(GL_TEXTURE_2D, materials[i].Texture.ID); // logWrite("UR MOM4"); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); int type = materials[i].Texture.type == GL_RGB ? 3 : 4; // logWrite("UR MOM5"); // glTexImage2D(GL_TEXTURE_2D, 0, type, materials[i].Texture.width, materials[i].Texture.height, 0, type, // GL_UNSIGNED_BYTE, materials[i].Texture.imageData); // glTexImage2D(GL_TEXTURE_2D, 0, type, materials[i].Texture.width, materials[i].Texture.height, 0, type, // GL_UNSIGNED_BYTE, materials[i].Texture.imageData); fprintf(stderr, "texture begin"); // std::cout << type << std::endl; std::cout << materials[i].Texture.type; glTexImage2D(GL_TEXTURE_2D, 0, type, materials[i].Texture.width, materials[i].Texture.height, 0, materials[i].Texture.type, GL_UNSIGNED_BYTE, materials[i].Texture.imageData); // logWrite("UR MOM6"); fprintf(stderr, "texture end"); } float fps; float curtime; int total_frames; fread( &fps, sizeof( float ), 1, mdlFile ); fread( &curtime, sizeof( float ), 1, mdlFile ); fread( &total_frames, sizeof( int ), 1, mdlFile ); fread( &numJoints, sizeof( unsigned short ), 1, mdlFile ); totalframes = total_frames; totaltime = total_frames * (1000.0 / fps); frametime = totaltime / totalframes; joints = new CMs3D_Skeleton_Joint[ numJoints ]; struct JointNameListRec { int jointIndex; char Name[32]; }; JointNameListRec *NameList = new JointNameListRec[ numJoints ]; for( int i = 0; i < numJoints; i++ ) { CMs3D_Joint *Joint = new CMs3D_Joint; fread( Joint, sizeof( CMs3D_Joint ), 1, mdlFile ); NameList[i].jointIndex = i; strcpy(NameList[i].Name, Joint->name); int j, parentIndex = -1; if( strlen( Joint->parentName ) > 0 ) { strcpy(joints[i].name,NameList[i].Name); for( j = 0; j < numJoints; j++ ) { if( stricmp( NameList[j].Name, Joint->parentName ) == 0 ) { parentIndex = NameList[j].jointIndex; break; } } } joints[i].localRotation[0] = Joint->rotation[0]; joints[i].localRotation[1] = Joint->rotation[1]; joints[i].localRotation[2] = Joint->rotation[2]; joints[i].localTranslation[0] = Joint->translation[0]; joints[i].localTranslation[1] = Joint->translation[1]; joints[i].localTranslation[2] = Joint->translation[2]; joints[i].parent = parentIndex; joints[i].numRotKeyframes = Joint->numRotKeyframes; joints[i].RotKeyframes = new CKeyframe [ joints[i].numRotKeyframes ]; joints[i].numTransKeyframes = Joint->numTransKeyframes; joints[i].TransKeyframes = new CKeyframe [ joints[i].numTransKeyframes ]; for( j = 0; j < Joint->numRotKeyframes; j++ ) { CMs3D_Keyframe *Keyframe = new CMs3D_Keyframe; fread( Keyframe, sizeof( CMs3D_Keyframe ), 1, mdlFile ); SetJointKeyframe( i, j, Keyframe->time * 1000.0f, Keyframe->parameter, true ); } for ( j = 0; j < Joint->numTransKeyframes; j++ ) { CMs3D_Keyframe *Keyframe = new CMs3D_Keyframe; fread( Keyframe, sizeof( CMs3D_Keyframe ), 1, mdlFile ); SetJointKeyframe( i, j, Keyframe->time * 1000.0f, Keyframe->parameter, false ); } } delete [] NameList; SetupJoints(); Restart(); fclose(mdlFile); }; void CMs3D::SetupJoints() { int i; for ( i = 0; i < numJoints; i++ ) { CMs3D_Skeleton_Joint &joint = joints[i]; joint.relative.setRotationRadians( joint.localRotation ); joint.relative.setTranslation( joint.localTranslation ); if ( joint.parent != -1 ) { joint.absolute = joints[joint.parent].absolute; joint.absolute = joint.absolute * joint.relative ; } else joint.absolute = joint.relative; } for ( i = 0; i < numVerts; i++ ) { CMs3D_Vertex *vertex = &verts[i]; if ( vertex->bone != -1 ) { CMatrix4 matrix = joints[vertex->bone].absolute; matrix.inverseTranslateVect( &vertex->coords ); matrix.inverseRotateVect( vertex->coords ); } } for ( i = 0; i < numFaces; i++ ) { CMs3D_Face &triangle = faces[i]; for ( int j = 0; j < 3; j++ ) { const CMs3D_Vertex *vertex = &verts[ triangle.vertexIndices[j] ]; if ( vertex->bone != -1 ) { CMatrix4 matrix = joints[ vertex->bone ].absolute; matrix.inverseRotateVect( triangle.normals[j] ); } } } }; void CMs3D::Restart( void ) { for( int i = 0; i < numJoints; i++ ) { joints[i].curRotKeyframe = 0; joints[i].curTransKeyframe = 0; joints[i].final = joints[i].absolute; } } void CMs3D::Animate( double time, bool rec ) { if( time > endtime ) { if( looping ) { Restart(); time = 0; } else if (!rec) { Restart(); anim_time = starttime; time = starttime; } } for( int i = 0; i < numJoints; i++ ) { float transVec[3]; CMatrix4 transform; int frame; CMs3D_Skeleton_Joint *Joint = &joints[i]; if ( Joint->numRotKeyframes == 0 && Joint->numTransKeyframes == 0 ) { Joint->final = Joint->absolute; continue; } frame = Joint->curTransKeyframe; while( frame < Joint->numTransKeyframes && Joint->TransKeyframes[frame].time < time ) { frame++; } Joint->curTransKeyframe = frame; if( frame == 0 ) memcpy( transVec, Joint->TransKeyframes[0].parameter, sizeof ( float )*3 ); else if( frame == Joint->numTransKeyframes ) memcpy( transVec, Joint->TransKeyframes[frame-1].parameter, sizeof ( float )*3 ); else { const CKeyframe &curFrame = Joint->TransKeyframes[frame]; const CKeyframe &prevFrame = Joint->TransKeyframes[frame-1]; float timeDelta = curFrame.time-prevFrame.time; float interpValue = ( float )(( time-prevFrame.time )/timeDelta ); transVec[0] = prevFrame.parameter[0]+( curFrame.parameter[0]-prevFrame.parameter[0] )*interpValue; transVec[1] = prevFrame.parameter[1]+( curFrame.parameter[1]-prevFrame.parameter[1] )*interpValue; transVec[2] = prevFrame.parameter[2]+( curFrame.parameter[2]-prevFrame.parameter[2] )*interpValue; } frame = Joint->curRotKeyframe; while ( frame < Joint->numRotKeyframes && Joint->RotKeyframes[frame].time < time ) { frame++; } Joint->curRotKeyframe = frame; if ( frame == 0 ) transform.setRotationRadians( Joint->RotKeyframes[0].parameter ); else if ( frame == Joint->numRotKeyframes ) transform.setRotationRadians( Joint->RotKeyframes[frame-1].parameter ); else { const CKeyframe &curFrame = Joint->RotKeyframes[frame]; const CKeyframe &prevFrame = Joint->RotKeyframes[frame-1]; float timeDelta = curFrame.time-prevFrame.time; float interpValue = ( float )(( time-prevFrame.time )/timeDelta ); float rotVec[3]; rotVec[0] = prevFrame.parameter[0]+( curFrame.parameter[0]-prevFrame.parameter[0] )*interpValue; rotVec[1] = prevFrame.parameter[1]+( curFrame.parameter[1]-prevFrame.parameter[1] )*interpValue; rotVec[2] = prevFrame.parameter[2]+( curFrame.parameter[2]-prevFrame.parameter[2] )*interpValue; transform.setRotationRadians( rotVec ); } transform.setTranslation( transVec ); CMatrix4 relativeFinal( Joint->relative ); relativeFinal = relativeFinal * transform ; if ( Joint->parent == -1 ) Joint->final = relativeFinal; else { Joint->final = joints[ Joint->parent ].final; Joint->final = Joint->final*relativeFinal; } } } void CMs3D::SetJointKeyframe( int jointIndex, int keyframeIndex, float time, float *parameter, bool isRotation ) { CKeyframe &keyframe = isRotation ? joints[jointIndex].RotKeyframes[keyframeIndex] : joints[jointIndex].TransKeyframes[keyframeIndex]; keyframe.joint = jointIndex; keyframe.time = time; memcpy( keyframe.parameter, parameter, sizeof( float )*3 ); } void CMs3D::DrawModel( double time ) { Animate( time , false); glDisable(GL_TEXTURE_2D); // glDisable(GL_BLEND); // glEnable(GL_LIGHTING); // glEnable( GL_CULL_FACE ); //glCullFace( GL_BACK ); //glEnable(GL_LIGHTING); // glEnable(GL_LIGHT0); // float lightColor[4] = {1, 1, 1, 1}; // glLightfv(GL_LIGHT0, GL_AMBIENT, lightColor); for( int i = 0; i < numGroups; i++ ) { int matindex = groups[i].materialIndex; if( matindex >= 0 ) { glMaterialfv( GL_FRONT, GL_AMBIENT, materials[ matindex ].ambient ); glMaterialfv( GL_FRONT, GL_DIFFUSE, materials[ matindex ].diffuse ); glMaterialfv( GL_FRONT, GL_SPECULAR, materials[ matindex ].specular ); glMaterialfv( GL_FRONT, GL_EMISSION, materials[ matindex ].emissive ); glMaterialf( GL_FRONT, GL_SHININESS, materials[ matindex ].shininess ); if( materials[groups[i].materialIndex].Texture.ID > 0 ) { // logWrite(materials[groups[i].materialIndex].Texture.ID); glBindTexture( GL_TEXTURE_2D, materials[groups[i].materialIndex].Texture.ID ); glEnable( GL_TEXTURE_2D ); // glDisable( GL_TEXTURE_2D ); } else { // glDisable( GL_TEXTURE_2D ); } } else { glDisable( GL_TEXTURE_2D ); } glBegin( GL_TRIANGLES ); for( int j = 0; j < groups[i].numtriangles; j++ ) { CMs3D_Face *tri = &faces[ groups[i].triangleIndices[j] ]; for( int k = 0; k < 3; k++ ) { if( verts[ tri->vertexIndices[k] ].bone == -1 ) { glTexCoord2f( tri->u[k], 1.0 - tri->v[k] ); glNormal3f( tri->normals[k].x, tri->normals[k].y, tri->normals[k].z ); glVertex3f( verts[ tri->vertexIndices[k] ].coords.x, verts[ tri->vertexIndices[k] ].coords.y, verts[ tri->vertexIndices[k] ].coords.z); } else { CMatrix4 final = joints[ verts[ tri->vertexIndices[k] ].bone ].final; glTexCoord2f( tri->u[k], 1.0 - tri->v[k] ); CVector3 newNormal( tri->normals[k] ); final.transform( newNormal ); newNormal.normalize(); glNormal3f( newNormal.x, newNormal.y, newNormal.z); CVector3 newVertex( verts[ tri->vertexIndices[k] ].coords.x,verts[ tri->vertexIndices[k] ].coords.y,verts[ tri->vertexIndices[k] ].coords.z ); //newVertex.normalize(); final.transform( newVertex ); glVertex3f( newVertex.x, newVertex.y, newVertex.z ); // glVertex3f( verts[ tri->vertexIndices[k] ].coords.x, verts[ tri->vertexIndices[k] //].coords.y, verts[ tri->vertexIndices[k] ].coords.z); } } } glEnd(); } std::cout << "ATTACHMENTSIZEzomg: " << attachments.size() << " " << std::endl; CMs3D* attachment; for (int a = 0; a < 1 ; a++) { std::cout << "ORLY: " << attachments.size() << " " << std::endl; fprintf(stderr, "ROFLMAO"); attachment = attachments[a]; for( int i = 0; i < attachment->numGroups; i++ ) { std::cout << "HURRAY"; int matindex = attachment->groups[i].materialIndex; if( matindex >= 0 ) { glMaterialfv( GL_FRONT, GL_AMBIENT, attachment->materials[ matindex ].ambient ); glMaterialfv( GL_FRONT, GL_DIFFUSE, attachment->materials[ matindex ].diffuse ); glMaterialfv( GL_FRONT, GL_SPECULAR, attachment->materials[ matindex ].specular ); glMaterialfv( GL_FRONT, GL_EMISSION, attachment->materials[ matindex ].emissive ); glMaterialf( GL_FRONT, GL_SHININESS, attachment->materials[ matindex ].shininess ); if( attachment->materials[attachment->groups[i].materialIndex].Texture.ID > 0 ) { // logWrite(attachment->materials[attachment->groups[i].materialIndex].Texture.ID); glBindTexture( GL_TEXTURE_2D, attachment->materials[attachment->groups[i].materialIndex].Texture.ID ); glEnable( GL_TEXTURE_2D ); } else { glDisable( GL_TEXTURE_2D ); } } else { glDisable( GL_TEXTURE_2D ); } glBegin( GL_TRIANGLES ); std::cout << "STARTING RENDERING"; for( int j = 0; j < attachment->groups[i].numtriangles; j++ ) { std::cout << "TRI1"; CMs3D_Face *tri = &(attachment->faces[ attachment->groups[i].triangleIndices[j] ]); std::cout << "TRI2"; for( int k = 0; k < 3; k++ ) { CMatrix4 final = joints[ attachment->parentjointnum ].final; std::cout << "SAFE"; glTexCoord2f( tri->u[k], 1.0 - tri->v[k] ); CVector3 newNormal( tri->normals[k] ); final.transform( newNormal ); newNormal.normalize(); glNormal3f( newNormal.x, newNormal.y, newNormal.z); CVector3 newVertex( attachment->verts[ tri->vertexIndices[k] ].coords.x,attachment->verts[ tri->vertexIndices[k] ].coords.y,attachment->verts[ tri->vertexIndices[k] ].coords.z ); //newVertex.normalize(); final.transform( newVertex ); glVertex3f( newVertex.x, newVertex.y, newVertex.z ); } } glEnd(); } } //glEnable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable( GL_CULL_FACE ); } void CMs3D::SetFramerange(double start, double end) { Restart(); starttime = start * frametime; anim_time = starttime; endtime = end * frametime; Animate(anim_time, false); } void CMs3D::AttachModel(CMs3D* model, char name[32]) { std::cout << joints[numJoints].name; for (int i=0;ijoints[i].name); std::cout << "CRASH"; if (strcmp(joints[i].name,name) == 0) { std::cout << "LOLZ"; std::cout << "ATTACHEDkek"; attachments.push_back(model); attachments[attachments.size()-1]->parentjointnum = i; std::cout << "SIZE:" << attachments.size(); std::cout << "ATTACHED1"; // attachments[attachments.size()]->parentjointnum = i; std::cout << "ATTACHED"; break; }; std::cout << "CRASH2" << " " << i << std::endl << numJoints; } std::cout << "AFTER FOR"; } /* void CMs3D::DetachModel() { delete attachment; }*/