I’ve got this class that’s suppose to load MD2 model. I don’t really know how to apply it an actual mesh in the scene? I do know that once I have the mesh I need to do this
Vector2[] UV = new Vector2[mNumTriangles*3];
int k = 0;
for( int i = 0; i < mNumTriangles; i++ )
{
UV[k] = mTexCoords[mTriangles[i].mTexIndices[0]];
UV[k+1] = mTexCoords[mTriangles[i].mTexIndices[0]];
UV[k+2] = mTexCoords[mTriangles[i].mTexIndices[0]];
}
mesh.vertices = mVertices;
mesh.uv = UV;
Anyways, any help on hooking this up in a scene would be of great help!
Here’s the class (the drawing function is temporary, it can be changed to work :p)
sing UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using System;
public struct MD2Header
{
public int mMagic; // 844121161 or "IDP2" - ( ('2' << 24) + ('P' << 16) + ('D' << 8) + 'I' )
public int mVersion; // 8
public int mSkinWidth; // Texture width
public int mSkinHeight; // Texture height
public int mFrameSize; // A single frame's size in bytes
public int mNumSkins; // Number of textures with the model
public int mNumVertices; // Number of vertices per frame
public int mNumTexCoords; // Number of texture coordinates
public int mNumTriangles; // Number of triangles per frame
public int mNumGLCommands; // Number of OGL commands
public int mNumFrames; // Number of frames
public int mSkinsOffset; // Position in bytes from the start to the texture names
public int mTexCoordsOffset; // Position in bytes from the start to the texture coords
public int mTrianglesOffset; // Position in bytes from the start to the triangle list
public int mFramesOffset; // Position in bytes from the start to the frames list
public int mGLCommandsOffset; // Position in bytes from the start to the OGL commands list
public int mEndOffset; // Position in bytes from the start to the end of the file
}
public struct MD2Vertex
{
public byte[] mVerts; // Compressed vertices
public byte mLightNormalIndex; // Index into an array of normals by ID software
}
// float vect[3];
//vect[i] = (mVertices.mVerts[i] * mScale[i]) + mTranslate[i];
public struct MD2Frame
{
public float[] mScale;
public float[] mTranslate;
public byte[] name;
public MD2Vertex[] mVertices;
}
public struct MD2Triangle
{
public short[] mVertIndices;
public short[] mTexIndices;
}
// Divide u by SkinWidth and v by SkinHeight to get real tex coords
public struct MD2TexCoordShort
{
public short u, v;
}
public struct MD2TexCoord
{
public float u, v;
}
public struct MD2GLCommandVertex
{
public float s, t;
public int VertIndex;
}
public struct Animation
{
public int mFirstFrame; // 1st frame of the animation
public int mLastFrame; // Number of frame (animate mFirstFrame through mFirstFrame + mLastFrame)
public int mFPS; // frames per second
}
public struct AnimationState
{
public int mStartFrame; // first frame
public int mEndFrame; // last frame
public int mFps; // fps
/* interpolation */
public float mTime; // current time
public float mOldTime; // Old time
public float mInterpolation; // The actual interpolation
public int mType; // Animation type (STAND, RUN, ATTACK, ect..)
public int mFrame; // Current frame
public int mNextFrame; // Next frame
public bool mLoop; // Does the animation loop?
public bool mIncrease; // Should me increase the next frame (for non looping anim)
}
public class CModelMD2 : MonoBehaviour
{
private int mNumVerts; // Vertices per frame
private int mNumFrames; // Total number of frames in the model
private int mNumTexCoords; // Number of texture coordinates
private int mNumSkins;
private int mNumTriangles;
private Vector3[] mVertices;
private Vector2[] mTexCoords;
private MD2Frame[] mFrames;
private MD2Triangle[] mTriangles;
private MD2TexCoordShort[] mCompressedTexCoords;
private AnimationState mAnimation; // The Current animation state
public void LoadModel( string filename )
{
FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
BinaryReader pFile = new BinaryReader(fs);
MD2Header header;
// Read in the header
byte[] buff = pFile.ReadBytes(Marshal.SizeOf(typeof(MD2Header)));//read the header as binary data
GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned); //prevent the GC from affecting the buffer
header = (MD2Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MD2Header)); //get the header from the buffer
handle.Free();
if( header.mMagic != 844121161 || header.mVersion != 8 )
{
return;
}
mNumVerts = header.mNumVertices;
mNumFrames = header.mNumFrames;
mNumTexCoords = header.mNumTexCoords;
mNumTriangles = header.mNumTriangles;
mNumSkins = header.mNumSkins;
mVertices = new Vector3[mNumVerts * mNumFrames];
mFrames = new MD2Frame[mNumFrames * header.mFrameSize];
mTriangles = new MD2Triangle[mNumTriangles];
mTexCoords = new Vector2[mNumTexCoords];
mCompressedTexCoords = new MD2TexCoordShort[mNumTexCoords];
// Read in the texture coords
pFile.BaseStream.Seek( header.mTexCoordsOffset, SeekOrigin.Begin );
for(int i = 0; i < mNumTexCoords; i++ )
{
buff = pFile.ReadBytes(Marshal.SizeOf(typeof(MD2TexCoordShort)));//read the header as binary data
handle = GCHandle.Alloc(buff, GCHandleType.Pinned); //prevent the GC from affecting the buffer
mCompressedTexCoords[i] = (MD2TexCoordShort)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MD2TexCoordShort)); //get the header from the buffer
handle.Free();
// Get the real tex coords
mTexCoords[i].x = mCompressedTexCoords[i].u / (float)header.mSkinWidth;
mTexCoords[i].y = mCompressedTexCoords[i].v / (float)header.mSkinHeight;
mTexCoords[i].y = 1.0f - mTexCoords[i].y;
}
// Read in the triangles
pFile.BaseStream.Seek( header.mTrianglesOffset, SeekOrigin.Begin );
for(int i = 0; i < mNumTriangles; i++ )
{
buff = pFile.ReadBytes(Marshal.SizeOf(typeof(MD2Triangle)));//read the header as binary data
handle = GCHandle.Alloc(buff, GCHandleType.Pinned); //prevent the GC from affecting the buffer
mTriangles[i] = (MD2Triangle)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MD2Triangle)); //get the header from the buffer
handle.Free();
}
// Read in the frames
pFile.BaseStream.Seek( header.mFramesOffset, SeekOrigin.Begin );
for(int i = 0; i < mNumTriangles; i++ )
{
buff = pFile.ReadBytes(Marshal.SizeOf(typeof(MD2Frame)));//read the header as binary data
handle = GCHandle.Alloc(buff, GCHandleType.Pinned); //prevent the GC from affecting the buffer
mFrames[i] = (MD2Frame)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MD2Frame)); //get the header from the buffer
handle.Free();
}
// read in the vertices
int k = 0;
for( int i = 0; i < mNumFrames; i++ )
{
for( int j = 0; j < mNumVerts; j++ )
{
mVertices[k].x = (mFrames[i].mVertices[j].mVerts[0] * mFrames[i].mScale[0]) + mFrames[i].mTranslate[0];
mVertices[k].y = (mFrames[i].mVertices[j].mVerts[1] * mFrames[i].mScale[1]) + mFrames[i].mTranslate[1];
mVertices[k].z = (mFrames[i].mVertices[j].mVerts[2] * mFrames[i].mScale[2]) + mFrames[i].mTranslate[2];
k++;
}
}
}
public void DrawFrame( int frame, Mesh mesh )
{
Vector2[] UV = new Vector2[mNumTriangles*3];
int k = 0;
for( int i = 0; i < mNumTriangles; i++ )
{
UV[k] = mTexCoords[mTriangles[i].mTexIndices[0]];
UV[k+1] = mTexCoords[mTriangles[i].mTexIndices[0]];
UV[k+2] = mTexCoords[mTriangles[i].mTexIndices[0]];
}
mesh.vertices = mVertices;
mesh.uv = UV;
}
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update () {
}
}