/// <summary> /// Copy values to another matrix. /// </summary> /// <param name="mtx44">Other matrix.</param> public void CopyValuesTo(MTX44 m) { for (int i = 0; i < 4 * 4; ++i) { m._array[i] = this[i]; } }
/// <summary> /// Clone this matrix. /// </summary> /// <returns>Clone of matrix.</returns> public MTX44 Clone() { var clone = new MTX44(); for (var i = 0; i < 4*4; ++i) { clone._array[i] = _array[i]; } return clone; }
public void translate(float x, float y, float z) { MTX44 b = new MTX44(); b.LoadIdentity(); b[12] = x; b[13] = y; b[14] = z; MultMatrix(b).CopyValuesTo(this); }
/// <summary> /// Clone this matrix. /// </summary> /// <returns>Clone of matrix.</returns> public MTX44 Clone() { var clone = new MTX44(); for (var i = 0; i < 4 * 4; ++i) { clone._array[i] = _array[i]; } return(clone); }
/// <summary> /// Scale this matrix. /// </summary> /// <param name="x">X scale factor.</param> /// <param name="y">Y scale factor.</param> /// <param name="z">Z scale factor.</param> public void Scale(float x, float y, float z) { MTX44 m = new MTX44(); m.LoadIdentity(); m[0] = x; m[5] = y; m[10] = z; this.MultMatrix(m).CopyValuesTo(this); }
/// <summary> /// Multiplicate this matrix with another. /// </summary> /// <param name="b">Other matrix.</param> /// <returns>Multiplication result.</returns> public MTX44 MultMatrix(MTX44 b) { MTX44 m = new MTX44(); MTX44 a = this; int i, j, k; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { m._array[(i << 2) + j] = 0.0f; for (k = 0; k < 4; k++) { m._array[(i << 2) + j] += a._array[(k << 2) + j] * b._array[(i << 2) + k]; } } } return(m); }
/// <summary> /// Copy values to another matrix. /// </summary> /// <param name="mtx44">Other matrix.</param> public void CopyValuesTo(MTX44 m) { for (int i = 0; i < 4*4; ++i) m._array[i] = this[i]; }
/// <summary> /// Ctor. /// </summary> public NsbmdGlRenderer() { // Init matrix stack. for (int i = 0; i < MatrixStack.Length; ++i) MatrixStack[i] = new MTX44(); }
/// <summary> /// Process polygon 3d commands. /// </summary> /// <param name="polydata">Data of specific polygon.</param> private static void Process3DCommand(byte[] polydata) { if (polydata == null) return; int commandptr = 0; int commandlimit = polydata.Length; int[] command = new int[4]; int cur_vertex, mode, i; float[] vtx_state = {0.0f, 0.0f, 0.0f}; float[] vtx_trans = {0.0f, 0.0f, 0.0f}; cur_vertex = gCurrentVertex; // for vertex_mode CurrentMatrix = MatrixStack[stackID].Clone(); while (commandptr < commandlimit) { for (i = 0; i < 4; ++i) { if (commandptr >= commandlimit) command[i] = 0xFF; else { command[i] = polydata[commandptr]; commandptr++; } } for (i = 0; i < 4 && commandptr < commandlimit; i++) { switch (command[i]) { case 0: // No Operation (for padding packed GXFIFO commands) break; case 0x14: /* MTX_RESTORE - Restore Current Matrix from Stack (W) Sets C=[N]. The stack pointer S is not used, and is left unchanged. Parameter Bit0-4: Stack Address (0..30) (31 causes overflow in GXSTAT.15) Parameter Bit5-31: Not used */ stackID = Utils.Read4BytesAsInt32(polydata, commandptr) & 0x0000001F; commandptr += 4; CurrentMatrix = MatrixStack[stackID].Clone(); break; case 0x1b: /* MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) Sets C=M*C. Parameters: 3, m[0..2] (MTX_SCALE doesn't change Vector Matrix) */ { int x, y, z; x = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; y = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; z = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; CurrentMatrix.Scale(x/SCALE_IV, y/SCALE_IV, z/SCALE_IV); break; } case 0x20: // Directly Set Vertex Color (W) { int rgb, r, g, b; rgb = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; if (gOptColoring) { r = (rgb >> 0) & 0x1F; g = (rgb >> 5) & 0x1F; b = (rgb >> 10) & 0x1F; Gl.glColor3f(((float) r)/31.0f, ((float) g)/31.0f, ((float) b)/31.0f); } } break; case 0x21: /* Set Normal Vector (W) 0-9 X-Component of Normal Vector (1bit sign + 9bit fractional part) 10-19 Y-Component of Normal Vector (1bit sign + 9bit fractional part) 20-29 Z-Component of Normal Vector (1bit sign + 9bit fractional part) 30-31 Not used */ { int xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xyz >> 0) & 0x3FF; if ((x & 0x200) != 0) x |= -1024; y = (xyz >> 10) & 0x3FF; if ((y & 0x200) != 0) y |= -1024; z = (xyz >> 20) & 0x3FF; if ((z & 0x200) != 0) z |= -1024; Gl.glNormal3f(((float) x)/512.0f, ((float) y)/512.0f, ((float) z)/512.0f); break; } case 0x22: /* Set Texture Coordinates (W) Parameter 1, Bit 0-15 S-Coordinate (X-Coordinate in Texture Source) Parameter 1, Bit 16-31 T-Coordinate (Y-Coordinate in Texture Source) Both values are 1bit sign + 11bit integer + 4bit fractional part. A value of 1.0 (=1 SHL 4) equals to one Texel. */ { int st, s, t; st = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; s = (st >> 0) & 0xffff; if ((s & 0x8000) != 0) s |= -65536; t = (st >> 16) & 0xffff; if ((t & 0x8000) != 0) t |= -65536; Gl.glTexCoord2f(((float) s)/16.0f, ((float) t)/16.0f); break; } case 0x23: /* VTX_16 - Set Vertex XYZ Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Y-Coordinate (signed, with 12bit fractional part) Parameter 2, Bit 0-15 Z-Coordinate (signed, with 12bit fractional part) Parameter 2, Bit 16-31 Not used */ { int parameter, x, y, z; parameter = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (parameter >> 0) & 0xFFFF; if ((x & 0x8000) != 0) x |= -65536; y = (parameter >> 16) & 0xFFFF; if ((y & 0x8000) != 0) y |= -65536; parameter = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; z = parameter & 0xFFFF; if ((z & 0x8000) != 0) z |= -65536; vtx_state[0] = ((float) x)/SCALE_IV; vtx_state[1] = ((float) y)/SCALE_IV; vtx_state[2] = ((float) z)/SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x24: /* VTX_10 - Set Vertex XYZ Coordinates (W) Parameter 1, Bit 0-9 X-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 10-19 Y-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 20-29 Z-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 30-31 Not used */ { int xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xyz >> 0) & 0x3FF; if ((x & 0x200) != 0) x |= -1024; y = (xyz >> 10) & 0x3FF; if ((y & 0x200) != 0) y |= -1024; z = (xyz >> 20) & 0x3FF; if ((z & 0x200) != 0) z |= -1024; vtx_state[0] = ((float) x)/64.0f; vtx_state[1] = ((float) y)/64.0f; vtx_state[2] = ((float) z)/64.0f; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x25: /* VTX_XY - Set Vertex XY Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Y-Coordinate (signed, with 12bit fractional part) */ { int xy, x, y; xy = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xy >> 0) & 0xFFFF; if ((x & 0x8000) != 0) x |= -65536; y = (xy >> 16) & 0xFFFF; if ((y & 0x8000) != 0) y |= -65536; vtx_state[0] = ((float) x)/SCALE_IV; vtx_state[1] = ((float) y)/SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x26: /* VTX_XZ - Set Vertex XZ Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Z-Coordinate (signed, with 12bit fractional part) */ { int xz, x, z; xz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xz >> 0) & 0xFFFF; if ((x & 0x8000) != 0) x |= -65536; z = (xz >> 16) & 0xFFFF; if ((z & 0x8000) != 0) z |= -65536; vtx_state[0] = ((float) x)/SCALE_IV; vtx_state[2] = ((float) z)/SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x27: /* VTX_YZ - Set Vertex YZ Coordinates (W) Parameter 1, Bit 0-15 Y-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Z-Coordinate (signed, with 12bit fractional part) */ { int yz, y, z; yz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; y = (yz >> 0) & 0xFFFF; if ((y & 0x8000) != 0) y |= -65536; z = (yz >> 16) & 0xFFFF; if ((z & 0x8000) != 0) z |= -65536; vtx_state[1] = ((float) y)/SCALE_IV; vtx_state[2] = ((float) z)/SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x28: /* VTX_DIFF - Set Relative Vertex Coordinates (W) Parameter 1, Bit 0-9 X-Difference (signed, with 9bit fractional part) Parameter 1, Bit 10-19 Y-Difference (signed, with 9bit fractional part) Parameter 1, Bit 20-29 Z-Difference (signed, with 9bit fractional part) Parameter 1, Bit 30-31 Not used */ { int xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xyz >> 0) & 0x3FF; if ((x & 0x200) != 0) x |= -1024; y = (xyz >> 10) & 0x3FF; if ((y & 0x200) != 0) y |= -1024; z = (xyz >> 20) & 0x3FF; if ((z & 0x200) != 0) z |= -1024; vtx_state[0] += ((float) x)/SCALE_IV; vtx_state[1] += ((float) y)/SCALE_IV; vtx_state[2] += ((float) z)/SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } break; } case 0x40: // Start of Vertex List (W) { mode = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; switch (mode) { case 0: mode = Gl.GL_TRIANGLES; break; case 1: mode = Gl.GL_QUADS; break; case 2: mode = Gl.GL_TRIANGLE_STRIP; break; case 3: mode = Gl.GL_QUAD_STRIP; break; default: //return ;// FALSE;//throw new Exception(); break; } Gl.glBegin(mode); break; } case 0x41: // End of Vertex List (W) Gl.glEnd(); // for vertex mode, display at maximum certain number of vertex-list // decrease cur_vertex so that when we reach 0, stop rendering any further cur_vertex--; if (cur_vertex < 0 && gOptVertexMode) return; //TRUE; break; default: break; //return FALSE; } } } }
//MTX44[] mt; /// <summary> /// Render model to OpenGL surface. /// </summary> public void RenderModel(string file2, MKDS_Course_Editor.NSBTA.NSBTA.NSBTA_File ani, int[] aniframeS, int[] aniframeT, int[] aniframeScaleS, int[] aniframeScaleT, int[] aniframeR, MKDS_Course_Editor.NSBCA.NSBCA.NSBCA_File ca, RenderMode r, bool anim, bool anim2, int selectedanim, float X, float Y, float dist, float elev, float ang, bool licht, MKDS_Course_Editor.NSBTP.NSBTP.NSBTP_File p, Nsbmd nsb) { MTX44 tmp = new MTX44(); file = file2; for (var j = 0; j < Model.Polygons.Count - 1; j++) { var poly = Model.Polygons[j]; int matid = poly.MatId; var mat = Model.Materials[matid]; } int light = Gl.glIsEnabled(Gl.GL_LIGHTING); Gl.glDisable(Gl.GL_LIGHTING); Gl.glLineWidth(2.0F); /*float xmin = Model.boundXmin; float ymin = Model.boundYmin; float zmin = Model.boundZmin; float xmax = Model.boundXmax + Model.boundXmin; float ymax = Model.boundYmax +Model.boundYmin; float zmax = -Model.boundZmax +Model.boundZmin; float[][] box = {new float[] { xmin, ymin, zmin }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymax, zmin }, new float[]{ xmax, ymax, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymax, zmax }, new float[]{ xmin, ymax, zmax }, new float[]{ xmin, ymin, zmax }, new float[]{ xmin, ymin, zmax }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymax, zmax }, new float[]{ xmin, ymin, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymin, zmin }, new float[]{ xmin, ymin, zmax }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymax, zmin }, new float[]{ xmax, ymax, zmax }, new float[]{ xmin, ymax, zmax }, new float[]{ xmax, ymax, zmax } }; Gl.glColor3f(1.0F, 1.0F, 1.0F); Gl.glBegin(1); for(int i = 0; i < box.Length; i++) Gl.glVertex3f(box[i][0], box[i][1], box[i][2]); Gl.glEnd();*/ if (light == 1) { Gl.glEnable(Gl.GL_LIGHTING); } Gl.glLineWidth(1.0F); //float[] fmatrix = new float[64 * 16]; //float[] jmatrix = new float[Model.Objects.Count * 16]; //////////////////////////////////////////////////////////// // prepare the matrix stack for (var i = 0; i < Model.Objects.Count; i++) { var obj = Model.Objects[i]; var m_trans = obj.TransVect; if (obj.RestoreID != -1) Gl.glLoadMatrixf(MatrixStack[obj.RestoreID].Floats); if (obj.StackID != -1) { if (obj.Trans) Gl.glTranslatef(m_trans[0], m_trans[1], m_trans[2]); /*if ( obj.rot ) { mtx_Rotate( &tmp, obj->pivot, obj->neg, obj->a, obj->b ); glMultMatrixf( (GLfloat *)&tmp ); } // TODO */ Gl.glGetFloatv(Gl.GL_MODELVIEW_MATRIX, MatrixStack[obj.StackID].Floats); stackID = obj.StackID; // save the last stackID } } Gl.glLoadIdentity(); //////////////////////////////////////////////////////////// // display one polygon of the current model at a time //Todo //////////////////////////////////////////////////////////// // display all polygons of the current model for (var i = 0; i < Model.Polygons.Count - 1; i++) { var poly = Model.Polygons[i]; if (gOptTexture && !gOptWireFrame && g_mat) { int matid = poly.MatId; if (matid == -1) { Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); if (writevertex) { mattt.Add(new System.Windows.Media.ImageBrush()); } } else { if (writevertex) { mattt.Add(matt[matid]); } NsbmdMaterial mat = Model.Materials[matid]; if ((mat.format == 1 || mat.format == 6) && r != RenderMode.Translucent) continue; if ((mat.format == 0 || mat.format == 2 || mat.format == 3 || mat.format == 4 || mat.format == 5 || mat.format == 7) && r != RenderMode.Opaque) continue; Gl.glBindTexture(Gl.GL_TEXTURE_2D, matid + 1 + matstart); // Convert pixel coords to normalised STs Gl.glMatrixMode(Gl.GL_TEXTURE); Gl.glLoadIdentity(); if (p.Header.file_size != 0 && new List<string>(p.MPT.names).Contains(mat.MaterialName)) { NsbmdMaterial mmm = mat; int texid = 0; for (int l = 0; l < nsb.Textures.Count; l++) { if (nsb.Textures[l].texname == p.AnimData[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].KeyFrames[frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)]].texName) { texid = l; break; } } mmm.spdata = nsb.Textures[texid].spdata; mmm.texdata = nsb.Textures[texid].texdata; mmm.texname = nsb.Textures[texid].texname; mmm.texoffset = nsb.Textures[texid].texoffset; mmm.texsize = nsb.Textures[texid].texsize; mmm.width = nsb.Textures[texid].width; mmm.height = nsb.Textures[texid].height; mmm.format = nsb.Textures[texid].format; mmm.color0 = nsb.Textures[texid].color0; int palid = 0; for (int l = 0; l < nsb.Textures.Count; l++) { if (nsb.Palettes[l].palname == p.AnimData[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].KeyFrames[frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)]].palName) { palid = l; break; } } mmm.paldata = nsb.Palettes[palid].paldata; mmm.palname = nsb.Palettes[palid].palname; mmm.paloffset = nsb.Palettes[palid].paloffset; mmm.palsize = nsb.Palettes[palid].palsize; MakeTexture(matid, mmm); if (anim2) { if (nr[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] == Math.Round((float)(p.MPT.infoBlock.Data[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].Unknown1) / 512f)) { nr[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] = 0; if (frame[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] == p.MPT.NoFrames - 1) { frame[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] = 0; frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] = 0; } else { frame[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)]++; if (p.AnimData[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].KeyFrames.Length != frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] + 1) { if (frame[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] == p.AnimData[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].KeyFrames[frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)] + 1].Start) { frame_[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)]++; } } } } else { nr[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)]++;//= (float)p.MPT.infoBlock.Data[new List<string>(p.MPT.names).IndexOf(mat.MaterialName)].Unknown1 / 4096f; } } } try { if (ani.Header.file_size != 0 && new List<string>(ani.MAT.names).Contains(mat.MaterialName)) { int index = new List<string>(ani.MAT.names).IndexOf(mat.MaterialName); Gl.glScaled((double)ani.SRTData[index].scaleS[aniframeScaleS[index]], (double)ani.SRTData[index].scaleT[aniframeScaleT[index]], 1); Gl.glRotated((double)ani.SRTData[index].rotate[aniframeR[index]], 1, 0, 0); //Gl.glRotated((double)ani.SRTData[index].rotate[aniframeR[index] + 1], 0, 1, 0); Gl.glTranslated((double)ani.SRTData[index].translateS[aniframeS[index]], (double)ani.SRTData[index].translateT[aniframeT[index]], 0); if (anim2) { if (aniframeS[index] == ani.SRTData[index].translateS.Length - 1) { aniframeS[index] = 0; } else { aniframeS[index]++; } if (aniframeT[index] == ani.SRTData[index].translateT.Length - 1) { aniframeT[index] = 0; } else { aniframeT[index]++; } if (aniframeR[index] == (ani.SRTData[index].rotate.Length - 2) / 2) { aniframeR[index] = 0; } else { aniframeR[index]++; } if (aniframeScaleS[index] == ani.SRTData[index].scaleS.Length - 1) { aniframeScaleS[index] = 0; } else { aniframeScaleS[index]++; } if (aniframeScaleT[index] == ani.SRTData[index].scaleT.Length - 1) { aniframeScaleT[index] = 0; } else { aniframeScaleT[index]++; } } goto noscale; } else { goto scale; } } catch { } noscale: if (!mat.isEnvironmentMap) { Gl.glScalef(1.0f / ((float)mat.width), 1.0f / ((float)mat.height), 1.0f); } goto end; scale: if (!mat.isEnvironmentMap) { if (mat.mtx == null) { Gl.glScalef((float)mat.scaleS / ((float)mat.width), (float)mat.scaleT / ((float)mat.height), 1.0f); Gl.glRotatef(mat.rot, 0, 1, 0); Gl.glTranslatef(mat.transS, mat.transT, 0); } else { Gl.glScalef(1.0f / ((float)mat.width), 1.0f / ((float)mat.height), 1.0f); Gl.glMultMatrixf(mat.mtx); } } end: //Gl.glColor4f(1, 1, 0, 0); Gl.glEnable(Gl.GL_ALPHA_TEST); Gl.glAlphaFunc(Gl.GL_GREATER, 0f); Gl.glColor4f(0xff, 0xff, 0xff, 0xff);//(float)mat.Alpha / 31.0f); if (licht && (((mat.PolyAttrib >> 0) & 0x1) == 0 && ((mat.PolyAttrib >> 1) & 0x1) == 0 && ((mat.PolyAttrib >> 2) & 0x1) == 0 && ((mat.PolyAttrib >> 3) & 0x1) == 0) == false) { //Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 }); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, new float[] { 1, 1, 1, 0 }); Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_POSITION, new float[] { 1.0f, 1.0f, 1.0f, 0 }); Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_POSITION, new float[] { 1.0f, 1.0f, 1.0f, 0 }); Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); Gl.glEnable(Gl.GL_LIGHTING); if (((mat.PolyAttrib >> 0) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT0); else Gl.glDisable(Gl.GL_LIGHT0); if (((mat.PolyAttrib >> 1) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT1); else Gl.glDisable(Gl.GL_LIGHT1); if (((mat.PolyAttrib >> 2) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT2); else Gl.glDisable(Gl.GL_LIGHT2); if (((mat.PolyAttrib >> 3) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT3); else Gl.glDisable(Gl.GL_LIGHT3); if (mat.diffuseColor) { //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE); Gl.glColor4f((float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT); //Gl.glColor4f((float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR); //Gl.glColor4f((float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION); //Gl.glColor4f((float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f); //Gl.glEnable(Gl.GL_COLOR_MATERIAL); } // Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.Alpha / 31.0f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); //Gl.glEnable(Gl.GL_COLOR_MATERIAL); } else { Gl.glDisable(Gl.GL_LIGHTING); Gl.glDisable(Gl.GL_LIGHT0); Gl.glDisable(Gl.GL_LIGHT1); Gl.glDisable(Gl.GL_LIGHT2); Gl.glDisable(Gl.GL_LIGHT3); if (mat.diffuseColor) { //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE); Gl.glColor4f((float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT); //Gl.glColor4f((float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR); //Gl.glColor4f((float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f); //Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION); //Gl.glColor4f((float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f); //Gl.glEnable(Gl.GL_COLOR_MATERIAL); } //else //{ // Gl.glColor4f(1, 1, 1, 1); //Gl.glDisable(Gl.GL_COLOR_MATERIAL); //} } Gl.glEnable(Gl.GL_BLEND); if (mat.isEnvironmentMap) { Gl.glTexGeni(Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP); Gl.glTexGeni(Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP); Gl.glEnable(Gl.GL_TEXTURE_GEN_S); Gl.glEnable(Gl.GL_TEXTURE_GEN_T); //Gl.glBlendFunc(Gl.GL_ONE, Gl.GL_ONE); } else { Gl.glDisable(Gl.GL_TEXTURE_GEN_S); Gl.glDisable(Gl.GL_TEXTURE_GEN_T); Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); } int mode = -1; switch ((mat.PolyAttrib >> 4) & 0x3) { case 0: mode = Gl.GL_MODULATE; break; case 1: mode = Gl.GL_DECAL; break; case 2: mode = Gl.GL_MODULATE; break; case 3: mode = Gl.GL_MODULATE; break; } Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, mode); int cullmode = -1; //Gl.glEnable(Gl.GL_CULL_FACE); switch (mat.PolyAttrib >> 6 & 0x03) { case 0x03: cullmode = Gl.GL_NONE; break; case 0x02: cullmode = Gl.GL_BACK; break; case 0x01: cullmode = Gl.GL_FRONT; break; case 0x00: cullmode = Gl.GL_FRONT_AND_BACK; break; } Gl.glCullFace(cullmode); } } else { Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); } // Gl.glMatrixMode(Gl.GL_MODELVIEW_MATRIX); //Gl.glLoadIdentity(); if (!gOptColoring) { Gl.glColor3f(1, 1, 1); } stackID = poly.StackID; // the first matrix used by this polygon Process3DCommand(poly.PolyData, Model.Materials[poly.MatId], poly.JointID, true); /*if (MatrixStack[poly.StackID][0] == 0 && MatrixStack[poly.StackID][5] == 0 && MatrixStack[poly.StackID][10] == 0 && MatrixStack[poly.StackID][15] == 0) { } else { }*/ } writevertex = false; }
public static MTX44 mtx_Rotate(int pivot, int neg, float a, float b) { float[] data = new float[16]; data[15] = 1.0F; float one = 1.0F; float a2 = a; float b2 = b; switch (neg) { case 1: // '\001' case 3: // '\003' case 5: // '\005' case 7: // '\007' case 9: // '\t' case 11: // '\013' case 13: // '\r' case 15: // '\017' one = -1F; // fall through goto case 2; case 2: // '\002' case 4: // '\004' case 6: // '\006' case 8: // '\b' case 10: // '\n' case 12: // '\f' case 14: // '\016' default: switch (neg) { case 2: // '\002' case 3: // '\003' case 6: // '\006' case 7: // '\007' case 10: // '\n' case 11: // '\013' case 14: // '\016' case 15: // '\017' b2 = -b2; // fall through goto case 4; case 4: // '\004' case 5: // '\005' case 8: // '\b' case 9: // '\t' case 12: // '\f' case 13: // '\r' default: switch (neg) { case 4: // '\004' case 5: // '\005' case 6: // '\006' case 7: // '\007' case 12: // '\f' case 13: // '\r' case 14: // '\016' case 15: // '\017' a2 = -a2; // fall through goto case 8; case 8: // '\b' case 9: // '\t' case 10: // '\n' case 11: // '\013' default: switch (pivot) { case 0: // '\0' data[0] = one; data[5] = a; data[6] = b; data[9] = b2; data[10] = a2; break; case 1: // '\001' data[1] = one; data[4] = a; data[6] = b; data[8] = b2; data[10] = a2; break; case 2: // '\002' data[2] = one; data[4] = a; data[5] = b; data[8] = b2; data[9] = a2; break; case 3: // '\003' data[4] = one; data[1] = a; data[2] = b; data[9] = b2; data[10] = a2; break; case 4: // '\004' data[5] = one; data[0] = a; data[2] = b; data[8] = b2; data[10] = a2; break; case 5: // '\005' data[6] = one; data[0] = a; data[1] = b; data[8] = b2; data[9] = a2; break; case 6: // '\006' data[8] = one; data[1] = a; data[2] = b; data[5] = b2; data[6] = a2; break; case 7: // '\007' data[9] = one; data[0] = a; data[2] = b; data[4] = b2; data[6] = a2; break; case 8: // '\b' data[10] = one; data[0] = a; data[1] = b; data[4] = b2; data[5] = a2; break; case 9: // '\t' data[0] = -a; break; } break; } break; } break; } MTX44 matr = new MTX44(); matr._array = data; return(matr); }
public void translate(float x, float y, float z) { MTX44 b = new MTX44(); b.LoadIdentity(); b[12] = x; b[13] = y; b[14] = z; MultMatrix(b).CopyValuesTo(this); }
public void RipModel(string file) { NsbmdPolygon polygon; int matId; NsbmdMaterial material; int num3; DiffuseMaterial material2; MeshBuilder builder; Model3D modeld; MTX44 mtx = new MTX44(); List<MKDS_Course_Editor.Export3DTools.Group> list = new List<MKDS_Course_Editor.Export3DTools.Group>(); List<Vector3> list2 = new List<Vector3>(); for (int i = 0; i < (this.Model.Polygons.Count - 1); i++) { polygon = this.Model.Polygons[i]; matId = polygon.MatId; material = this.Model.Materials[matId]; } MTX44 mtx2 = new MTX44(); mtx2.LoadIdentity(); for (num3 = 0; num3 < this.Model.Objects.Count; num3++) { NsbmdObject obj2 = this.Model.Objects[num3]; float[] transVect = obj2.TransVect; float[] numArray2 = loadIdentity(); if (obj2.RestoreID != -1) { mtx2 = MatrixStack[obj2.RestoreID]; } if (obj2.StackID != -1) { if (obj2.visible) { MTX44 b = new MTX44(); b.SetValues(obj2.materix); mtx2 = mtx2.MultMatrix(b); } else { mtx2.Zero(); } MatrixStack[obj2.StackID] = mtx2; stackID = obj2.StackID; float[] numArray3 = mtx2.MultVector(new float[3]); list2.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); } } num3 = 0; while (num3 < (this.Model.Polygons.Count - 1)) { polygon = this.Model.Polygons[num3]; if ((gOptTexture && !gOptWireFrame) && g_mat) { matId = polygon.MatId; if (matId == -1) { this.mattt.Add(new ImageBrush()); } else { this.mattt.Add(this.matt[matId]); material = this.Model.Materials[matId]; } } stackID = polygon.StackID; list.Add(Process3DCommandRipper(polygon.PolyData, Model.Materials[polygon.MatId], polygon.JointID, true)); num3++; } File.Create(file).Close(); HelixToolkit.ObjExporter exporter = new HelixToolkit.ObjExporter(file, "Created with Spiky's DS Map Editor " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); int index = 0; foreach (MKDS_Course_Editor.Export3DTools.Group group in list) { ImageBrush brush = new ImageBrush(); try { brush.ImageSource = this.mattt[index].ImageSource; brush.Opacity = this.mattt[index].Opacity; brush.Viewbox = this.mattt[index].Viewbox; brush.ViewboxUnits = this.mattt[index].ViewboxUnits; brush.Viewport = this.mattt[index].Viewport; brush.ViewportUnits = this.mattt[index].ViewportUnits; } catch { } if (brush.ImageSource != null) { material2 = new DiffuseMaterial(brush); } else { material2 = new DiffuseMaterial(new SolidColorBrush()); } material2.SetValue(matName, this.Model.Materials[this.Model.Polygons[index].MatId].MaterialName); material2.SetValue(polyName, this.Model.Polygons[index].Name); material2.Brush.Opacity = ((float)this.Model.Materials[this.Model.Polygons[index].MatId].Alpha) / 31f; material2.AmbientColor = System.Windows.Media.Color.FromArgb(this.Model.Materials[this.Model.Polygons[index].MatId].AmbientColor.A, this.Model.Materials[this.Model.Polygons[index].MatId].AmbientColor.R, this.Model.Materials[this.Model.Polygons[index].MatId].AmbientColor.G, this.Model.Materials[this.Model.Polygons[index].MatId].AmbientColor.B); material2.Color = System.Windows.Media.Color.FromArgb(0xff, this.Model.Materials[this.Model.Polygons[index].MatId].DiffuseColor.R, this.Model.Materials[this.Model.Polygons[index].MatId].DiffuseColor.G, this.Model.Materials[this.Model.Polygons[index].MatId].DiffuseColor.B); builder = new MeshBuilder(); foreach (MKDS_Course_Editor.Export3DTools.Polygon polygon2 in group) { IList<Point3D> list3; IList<Vector3D> list4; IList<System.Windows.Point> list5; switch (polygon2.PolyType) { case PolygonType.Triangle: list3 = new List<Point3D>(); list4 = new List<Vector3D>(); list5 = new List<System.Windows.Point>(); num3 = 0; goto Label_08AB; case PolygonType.Quad: list3 = new List<Point3D>(); list4 = new List<Vector3D>(); list5 = new List<System.Windows.Point>(); num3 = 0; goto Label_0C5E; case PolygonType.TriangleStrip: list3 = new List<Point3D>(); list4 = new List<Vector3D>(); list5 = new List<System.Windows.Point>(); num3 = 0; goto Label_0D66; case PolygonType.QuadStrip: list3 = new List<Point3D>(); list4 = new List<Vector3D>(); list5 = new List<System.Windows.Point>(); num3 = 0; goto Label_0E7C; default: { continue; } } Label_0608: list3.Add(new Point3D((double)polygon2.Vertex[num3].X, (double)polygon2.Vertex[num3].Y, (double)polygon2.Vertex[num3].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3].X, (double)polygon2.Normals[num3].Y, (double)polygon2.Normals[num3].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3].X, (double)polygon2.TexCoords[num3].Y)); list3.Add(new Point3D((double)polygon2.Vertex[num3 + 1].X, (double)polygon2.Vertex[num3 + 1].Y, (double)polygon2.Vertex[num3 + 1].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3 + 1].X, (double)polygon2.Normals[num3 + 1].Y, (double)polygon2.Normals[num3 + 1].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3 + 1].X, (double)polygon2.TexCoords[num3 + 1].Y)); list3.Add(new Point3D((double)polygon2.Vertex[num3 + 2].X, (double)polygon2.Vertex[num3 + 2].Y, (double)polygon2.Vertex[num3 + 2].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3 + 2].X, (double)polygon2.Normals[num3 + 2].Y, (double)polygon2.Normals[num3 + 2].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3 + 2].X, (double)polygon2.TexCoords[num3 + 2].Y)); builder.AddTriangles(list3, list4, list5); list3.Clear(); list4.Clear(); list5.Clear(); num3 += 3; Label_08AB: if (num3 < polygon2.Vertex.Length) { goto Label_0608; } continue; Label_08E4: list3.Add(new Point3D((double)polygon2.Vertex[num3].X, (double)polygon2.Vertex[num3].Y, (double)polygon2.Vertex[num3].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3].X, (double)polygon2.Normals[num3].Y, (double)polygon2.Normals[num3].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3].X, (double)polygon2.TexCoords[num3].Y)); list3.Add(new Point3D((double)polygon2.Vertex[num3 + 1].X, (double)polygon2.Vertex[num3 + 1].Y, (double)polygon2.Vertex[num3 + 1].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3 + 1].X, (double)polygon2.Normals[num3 + 1].Y, (double)polygon2.Normals[num3 + 1].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3 + 1].X, (double)polygon2.TexCoords[num3 + 1].Y)); list3.Add(new Point3D((double)polygon2.Vertex[num3 + 2].X, (double)polygon2.Vertex[num3 + 2].Y, (double)polygon2.Vertex[num3 + 2].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3 + 2].X, (double)polygon2.Normals[num3 + 2].Y, (double)polygon2.Normals[num3 + 2].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3 + 2].X, (double)polygon2.TexCoords[num3 + 2].Y)); list3.Add(new Point3D((double)polygon2.Vertex[num3 + 3].X, (double)polygon2.Vertex[num3 + 3].Y, (double)polygon2.Vertex[num3 + 3].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3 + 3].X, (double)polygon2.Normals[num3 + 3].Y, (double)polygon2.Normals[num3 + 3].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3 + 3].X, (double)polygon2.TexCoords[num3 + 3].Y)); builder.AddQuads(list3, list4, list5); list3.Clear(); list4.Clear(); list5.Clear(); num3 += 4; Label_0C5E: if (num3 < polygon2.Vertex.Length) { goto Label_08E4; } continue; Label_0C97: list3.Add(new Point3D((double)polygon2.Vertex[num3].X, (double)polygon2.Vertex[num3].Y, (double)polygon2.Vertex[num3].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3].X, (double)polygon2.Normals[num3].Y, (double)polygon2.Normals[num3].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3].X, (double)polygon2.TexCoords[num3].Y)); num3++; Label_0D66: if (num3 < polygon2.Vertex.Length) { goto Label_0C97; } builder.AddTriangleStrip(list3, list4, list5); continue; Label_0DAD: list3.Add(new Point3D((double)polygon2.Vertex[num3].X, (double)polygon2.Vertex[num3].Y, (double)polygon2.Vertex[num3].Z)); list4.Add(new Vector3D((double)polygon2.Normals[num3].X, (double)polygon2.Normals[num3].Y, (double)polygon2.Normals[num3].Z)); list5.Add(new System.Windows.Point((double)polygon2.TexCoords[num3].X, (double)polygon2.TexCoords[num3].Y)); num3++; Label_0E7C: if (num3 < polygon2.Vertex.Length) { goto Label_0DAD; } builder.AddTriangleStrip(list3, list4, list5); } modeld = new GeometryModel3D(builder.ToMesh(false), material2); exporter.Export(modeld); index++; } exporter.Close(); this.writevertex = false; }
/// <summary> /// Ctor. /// </summary> public NsbmdGlRenderer(int matstart) { this.matstart = matstart; // Init matrix stack. for (int i = 0; i < MatrixStack.Length; ++i) MatrixStack[i] = new MTX44(); }
/// <summary> /// Render model to OpenGL surface. /// </summary> public void RenderModel(float elev, float ang) { MTX44 tmp = new MTX44(); for (var j = 0; j < Model.Polygons.Count - 1; j++) { var poly = Model.Polygons[j]; int matid = poly.MatId; var mat = Model.Materials[matid]; } // int light = Gl.glIsEnabled(Gl.GL_LIGHTING); //Gl.glDisable(Gl.GL_LIGHTING); Gl.glLineWidth(2.0F); float xmin = Model.boundXmin; float ymin = Model.boundYmin; float zmin = Model.boundZmin; float xmax = Model.boundXmax + Model.boundXmin; float ymax = Model.boundYmax + Model.boundYmin; float zmax = -Model.boundZmax + Model.boundZmin; /*float[][] box = {new float[] { xmin, ymin, zmin }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymax, zmin }, new float[]{ xmax, ymax, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymax, zmax }, new float[]{ xmin, ymax, zmax }, new float[]{ xmin, ymin, zmax }, new float[]{ xmin, ymin, zmax }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymax, zmax }, new float[]{ xmin, ymin, zmin }, new float[]{ xmin, ymax, zmin }, new float[]{ xmin, ymin, zmin }, new float[]{ xmin, ymin, zmax }, new float[]{ xmax, ymin, zmin }, new float[]{ xmax, ymin, zmax }, new float[]{ xmax, ymax, zmin }, new float[]{ xmax, ymax, zmax }, new float[]{ xmin, ymax, zmax }, new float[]{ xmax, ymax, zmax } };*/ //Gl.glColor3f(1.0F, 1.0F, 1.0F); //Gl.glBegin(1); //for (int i = 0; i < box.Length; i++) //Gl.glVertex3f(box[i][0], box[i][1], box[i][2]); //Gl.glEnd(); //if (light == 1) //{ // Gl.glEnable(Gl.GL_LIGHTING); //} Gl.glLineWidth(1.0F); //float[] fmatrix = new float[64 * 16]; //float[] jmatrix = new float[Model.Objects.Count * 16]; //////////////////////////////////////////////////////////// // prepare the matrix stack for (var i = 0; i < Model.Objects.Count; i++) { var obj = Model.Objects[i]; var m_trans = obj.TransVect; float[] f = loadIdentity(); if (obj.RestoreID != -1) { Gl.glLoadMatrixf(MatrixStack[obj.RestoreID].Floats); } if (obj.StackID != -1) { //doJointAnimation(ca, selectedanim, anim, i); Gl.glMultMatrixf(obj.materix); if (obj.isBillboard) { if (!obj.isYBillboard) { Gl.glRotatef(elev, 1, 0, 0); } Gl.glRotatef(-ang, 0, 1, 0); } Gl.glGetFloatv(Gl.GL_MODELVIEW_MATRIX, MatrixStack[obj.StackID].Floats); stackID = obj.StackID; // save the last stackID } else { } if (obj.visible) { //light = Gl.glIsEnabled(Gl.GL_LIGHTING); //Gl.glDisable(Gl.GL_LIGHTING); //drawJoint(0.1f); //if (light == 1) //{ // Gl.glEnable(Gl.GL_LIGHTING); //} } //Gl.glColor4f(0xff, 0xff, 0xff, 0xff); //int index = new List<string>(ca.JNT0.names).IndexOf(obj.Name); //Gl.glTranslatef(ca.JAC[index].ObjInfo[0].translate[0][0], ca.JAC[index].ObjInfo[0].translate[0][1], ca.JAC[index].ObjInfo[0].translate[0][2]); } Gl.glLoadIdentity(); /*for (int i = 0; i < Model.Objects.Count; i++) { if (Model.Objects[i].ParentID != -1 && Model.Objects[i].StackID != -1) { //light = Gl.glIsEnabled(Gl.GL_LIGHTING); //Gl.glDisable(Gl.GL_LIGHTING); //setColor(4, null); Gl.glLineWidth(2.0F); Gl.glBegin(1); float[] mtx = loadIdentity(); if (Model.Objects[Model.Objects[i].ParentID].RestoreID != -1) { //Gl.glLoadMatrixf(MatrixStack[obj.RestoreID].Floats); //mtx = multMatrix(mtx, MatrixStack[Model.Objects[Model.Objects[i].ParentID].RestoreID].Floats); } if (Model.Objects[Model.Objects[i].ParentID].StackID != -1) { //Gl.glMultMatrixf(Model.Objects[obj.ParentID].materix); mtx = multMatrix(mtx, MatrixStack[Model.Objects[Model.Objects[i].ParentID].StackID].Floats); } float[] xyz = pullVector(mtx, 0); Gl.glVertex3f(xyz[0], xyz[1], xyz[2]); //Gl.glLoadIdentity(); mtx = loadIdentity(); if (Model.Objects[i].RestoreID != -1) { //Gl.glLoadMatrixf(MatrixStack[obj.RestoreID].Floats); //mtx = multMatrix(mtx, MatrixStack[Model.Objects[i].RestoreID].Floats); } if (Model.Objects[Model.Objects[i].ParentID].StackID != -1) { //Gl.glMultMatrixf(Model.Objects[obj.ParentID].materix); mtx = multMatrix(mtx, MatrixStack[Model.Objects[i].StackID].Floats); } xyz = pullVector(mtx, 0); Gl.glVertex3f(xyz[0], xyz[1], xyz[2]); Gl.glEnd(); //if (light == 1) //{ // Gl.glEnable(Gl.GL_LIGHTING); // } Gl.glLineWidth(1.0F); } }*/ //Gl.glColor4f(0xff, 0xff, 0xff, 0xff); Gl.glLoadIdentity(); //Gl.glColor4f(0xff, 0xff, 0xff, 0xff); //////////////////////////////////////////////////////////// // display one polygon of the current model at a time //Todo //////////////////////////////////////////////////////////// // display all polygons of the current model for (var i = 0; i < Model.Polygons.Count - 1; i++) { var poly = Model.Polygons[i]; if (gOptTexture && !gOptWireFrame && g_mat) { int matid = poly.MatId; if (matid == -1) { Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); if (writevertex) { mattt.Add(new System.Windows.Media.ImageBrush()); } } else { if (writevertex) { mattt.Add(matt[matid]); } var mat = Model.Materials[matid]; //if ((mat.format == 1 || mat.format == 6) && r != RenderMode.Translucent) continue; //if ((mat.format == 0 || mat.format == 2 || mat.format == 3 || mat.format == 4 || mat.format == 5 || mat.format == 7) && r != RenderMode.Opaque) continue; Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); // Convert pixel coords to normalised STs Gl.glMatrixMode(Gl.GL_TEXTURE); Gl.glLoadIdentity(); /*try { if (ani.Header.file_size != 0 && new List<string>(ani.MAT.names).Contains(mat.MaterialName)) { int index = new List<string>(ani.MAT.names).IndexOf(mat.MaterialName); Gl.glScaled((double)ani.SRTData[index].scaleS[aniframeScaleS[index]], (double)ani.SRTData[index].scaleT[aniframeScaleT[index]], 1); Gl.glRotated((double)ani.SRTData[index].rotate[aniframeR[index]], 1, 0, 0); Gl.glTranslated((double)ani.SRTData[index].translateS[aniframeS[index]], (double)ani.SRTData[index].translateT[aniframeT[index]], 0); if (anim2) { if (aniframeS[index] == ani.SRTData[index].translateS.Length - 1) { aniframeS[index] = 0; } else { aniframeS[index]++; } if (aniframeT[index] == ani.SRTData[index].translateT.Length - 1) { aniframeT[index] = 0; } else { aniframeT[index]++; } if (aniframeR[index] == ani.SRTData[index].rotate.Length - 1) { aniframeR[index] = 0; } else { aniframeR[index]++; } if (aniframeScaleS[index] == ani.SRTData[index].scaleS.Length - 1) { aniframeScaleS[index] = 0; } else { aniframeScaleS[index]++; } if (aniframeScaleT[index] == ani.SRTData[index].scaleT.Length - 1) { aniframeScaleT[index] = 0; } else { aniframeScaleT[index]++; } } goto noscale; } else { goto scale; } } catch { } noscale: if (!mat.isEnvironmentMap) { Gl.glScalef(1.0f / ((float)mat.width), 1.0f / ((float)mat.height), 1.0f); } goto end;*/ scale: if (!mat.isEnvironmentMap) { Gl.glScalef((float)mat.scaleS / ((float)mat.width), (float)mat.scaleT / ((float)mat.height), 1.0f); } end: //Gl.glColor4f(1, 1, 0, 0); Gl.glEnable(Gl.GL_ALPHA_TEST); Gl.glAlphaFunc(Gl.GL_GREATER, 0f); //Gl.glColor4f(0xff, 0xff, 0x00, 0x00);//(float)mat.Alpha / 31.0f); if (((mat.PolyAttrib >> 0xf) & 0x1) == 1 && (((mat.PolyAttrib >> 0) & 0x1) == 0 && ((mat.PolyAttrib >> 1) & 0x1) == 0 && ((mat.PolyAttrib >> 2) & 0x1) == 0 && ((mat.PolyAttrib >> 2) & 0x1) == 0) == false) { //Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); //Gl.glLightfv(Gl.GL_LIGHT3, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); Gl.glEnable(Gl.GL_LIGHTING); if (((mat.PolyAttrib >> 0) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT0); else Gl.glDisable(Gl.GL_LIGHT0); if (((mat.PolyAttrib >> 1) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT1); else Gl.glDisable(Gl.GL_LIGHT1); if (((mat.PolyAttrib >> 2) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT2); else Gl.glDisable(Gl.GL_LIGHT2); if (((mat.PolyAttrib >> 3) & 0x1) == 1) Gl.glEnable(Gl.GL_LIGHT3); else Gl.glDisable(Gl.GL_LIGHT3); Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE); Gl.glColor4f((float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f); Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT); Gl.glColor4f((float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f); Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR); Gl.glColor4f((float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f); Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION); Gl.glColor4f((float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE, new float[] { (float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.Alpha / 31.0f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT, new float[] { (float)mat.AmbientColor.R / 255f, (float)mat.AmbientColor.G / 255f, (float)mat.AmbientColor.B / 255f, (float)mat.AmbientColor.A / 255f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, new float[] { (float)mat.SpecularColor.R / 255f, (float)mat.SpecularColor.G / 255f, (float)mat.SpecularColor.B / 255f, (float)mat.SpecularColor.A / 255f }); //Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { (float)mat.EmissionColor.R / 255f, (float)mat.EmissionColor.G / 255f, (float)mat.EmissionColor.B / 255f, (float)mat.EmissionColor.A / 255f }); Gl.glEnable(Gl.GL_COLOR_MATERIAL); } else { Gl.glDisable(Gl.GL_LIGHTING); Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE); Gl.glColor4f((float)mat.DiffuseColor.R / 255f, (float)mat.DiffuseColor.G / 255f, (float)mat.DiffuseColor.B / 255f, (float)mat.DiffuseColor.A / 255f); Gl.glEnable(Gl.GL_COLOR_MATERIAL); } Gl.glEnable(Gl.GL_BLEND); if (mat.isEnvironmentMap) { Gl.glTexGeni(Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP); Gl.glTexGeni(Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP); Gl.glEnable(Gl.GL_TEXTURE_GEN_S); Gl.glEnable(Gl.GL_TEXTURE_GEN_T); //Gl.glBlendFunc(Gl.GL_ONE, Gl.GL_ONE); } else { Gl.glDisable(Gl.GL_TEXTURE_GEN_S); Gl.glDisable(Gl.GL_TEXTURE_GEN_T); Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); } int mode = -1; switch ((mat.PolyAttrib >> 4) & 0x3) { case 0: mode = Gl.GL_MODULATE; break; case 1: mode = Gl.GL_DECAL; break; case 2: mode = Gl.GL_MODULATE; break; case 3: mode = Gl.GL_MODULATE; break; } Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, mode); int cullmode = -1; //Gl.glEnable(Gl.GL_CULL_FACE); switch (mat.PolyAttrib >> 6 & 0x03) { case 0x03: cullmode = Gl.GL_NONE; break; case 0x02: cullmode = Gl.GL_BACK; break; case 0x01: cullmode = Gl.GL_FRONT; break; case 0x00: cullmode = Gl.GL_FRONT_AND_BACK; break; } Gl.glCullFace(cullmode); } } else { Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); } // Gl.glMatrixMode(Gl.GL_MODELVIEW_MATRIX); //Gl.glLoadIdentity(); if (!gOptColoring) { //Gl.glColor3f(1, 1, 1); } stackID = poly.StackID; // the first matrix used by this polygon Process3DCommand(poly.PolyData, Model.Materials[poly.MatId], poly.JointID, false); } writevertex = false; }
/// <summary> /// Multiplicate this matrix with another. /// </summary> /// <param name="b">Other matrix.</param> /// <returns>Multiplication result.</returns> public MTX44 MultMatrix(MTX44 b) { MTX44 m = new MTX44(); MTX44 a = this; int i, j, k; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { m._array[(i << 2) + j] = 0.0f; for (k = 0; k < 4; k++) m._array[(i << 2) + j] += a._array[(k << 2) + j]*b._array[(i << 2) + k]; } } return m; }
/// <summary> /// Scale this matrix. /// </summary> /// <param name="x">X scale factor.</param> /// <param name="y">Y scale factor.</param> /// <param name="z">Z scale factor.</param> public void Scale(float x, float y, float z) { MTX44 m = new MTX44(); m.LoadIdentity(); m[0] = x; m[5] = y; m[10] = z; this.MultMatrix(m).CopyValuesTo(this); }
/// <summary> /// Process polygon 3d commands. /// </summary> /// <param name="polydata">Data of specific polygon.</param> private void Process3DCommand(byte[] polydata, NsbmdMaterial m, int jointID, bool color) { Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glLoadIdentity(); HelixToolkit.MaterialHelper.CreateMaterial(new System.Windows.Media.ImageBrush()); md.Add(new HelixToolkit.MeshBuilder()); IList<System.Windows.Media.Media3D.Point3D> poi = new List<System.Windows.Media.Media3D.Point3D>(); IList<System.Windows.Media.Media3D.Vector3D> nor = new List<System.Windows.Media.Media3D.Vector3D>(); IList<System.Windows.Point> tex = new List<System.Windows.Point>(); int typ = -1; if (polydata == null) return; int commandptr = 0; int commandlimit = polydata.Length; int[] command = new int[4]; int cur_vertex, mode, i; float[] vtx_state = { 0.0f, 0.0f, 0.0f }; float[] vtx_trans = { 0.0f, 0.0f, 0.0f }; cur_vertex = gCurrentVertex; // for vertex_mode if (Model.Objects.Count > 0) { CurrentMatrix = MatrixStack[stackID].Clone(); } else { CurrentMatrix.LoadIdentity(); } if (Model.Objects.Count > 1) { //CurrentMatrix.Scale(Model.modelScale, Model.modelScale, Model.modelScale); } while (commandptr < commandlimit) { for (i = 0; i < 4; ++i) { if (commandptr >= commandlimit) command[i] = 0xFF; else { command[i] = polydata[commandptr]; commandptr++; } } for (i = 0; i < 4 && commandptr < commandlimit; i++) { switch (command[i]) { case 0: // No Operation (for padding packed GXFIFO commands) break; case 0x10: { int param = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; switch (param) { case 0: // Gl.glMatrixMode(Gl.GL_PROJECTION_MATRIX); break; case 1: // Gl.glMatrixMode(Gl.GL_MODELVIEW_MATRIX); break; case 2: break; case 3: // Gl.glMatrixMode(Gl.GL_TEXTURE_MATRIX); break; } break; } case 0x11: break; case 0x12: commandptr += 4; break; case 0x13: commandptr += 4; break; case 0x14: /* MTX_RESTORE - Restore Current Matrix from Stack (W) Sets C=[N]. The stack pointer S is not used, and is left unchanged. Parameter Bit0-4: Stack Address (0..30) (31 causes overflow in GXSTAT.15) Parameter Bit5-31: Not used */ stackID = Utils.Read4BytesAsInt32(polydata, commandptr) & 0x1F;// & 0x0000001F; commandptr += 4; MatrixStack[stackID].CopyValuesTo(CurrentMatrix); break; case 0x15: { CurrentMatrix.LoadIdentity(); break; } case 0x16: { for (int j = 0; j < 16; j++) { CurrentMatrix[j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f; commandptr += 4; } break; } case 0x17: { for (int j = 0; j < 4; j++) { for (int k = 0; k < 3; j++) { CurrentMatrix[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f; commandptr += 4; } } break; } case 0x18: { MTX44 f = new MTX44(); f.LoadIdentity(); for (int j = 0; j < 16; j++) { f[j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f; commandptr += 4; } CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix); break; } case 0x19: { MTX44 f = new MTX44(); f.LoadIdentity(); for (int j = 0; j < 4; j++) { for (int k = 0; k < 3; j++) { f[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f; commandptr += 4; } } CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix); break; } case 0x1A: { MTX44 f = new MTX44(); f.LoadIdentity(); for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; j++) { f[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f; commandptr += 4; } } CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix); break; } case 0x1b: /* MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) Sets C=M*C. Parameters: 3, m[0..2] (MTX_SCALE doesn't change Vector Matrix) */ { int x, y, z; x = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; y = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; z = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; //CurrentMatrix[0] = (float)sign(x, 32) / SCALE_IV; //CurrentMatrix[5] = (float)sign(y, 32) / SCALE_IV; //CurrentMatrix[10] = (float)sign(z, 32) / SCALE_IV; //CurrentMatrix.SetValues(scale(CurrentMatrix.Floats, x, y, z)); CurrentMatrix.Scale((float)x / SCALE_IV / Model.modelScale, (float)y / SCALE_IV / Model.modelScale, (float)z / SCALE_IV / Model.modelScale); //CurrentMatrix.Scale((float)sign(x, 32) / SCALE_IV, (float)sign(y, 32) / SCALE_IV, (float)sign(z, 32) / SCALE_IV); break; } case 0x1c: /* MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) Sets C=M*C. Parameters: 3, m[0..2] (x,y,z position) */ { int x, y, z; x = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; y = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; z = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; CurrentMatrix.translate((float)sign(x, 32) / SCALE_IV / Model.modelScale, (float)sign(y, 32) / SCALE_IV / Model.modelScale, (float)sign(z, 32) / SCALE_IV / Model.modelScale); break; } case 0x20: // Directly Set Vertex Color (W) { Int64 rgb, r, g, b; rgb = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; if (gOptColoring) { r = (rgb >> 0) & 0x1F; g = (rgb >> 5) & 0x1F; b = (rgb >> 10) & 0x1F; if (color) { Gl.glColor4f(((float)r) / 31.0f, ((float)g) / 31.0f, ((float)b) / 31.0f, m.Alpha / 31.0f); } } } break; case 0x21: /* Set Normal Vector (W) 0-9 X-Component of Normal Vector (1bit sign + 9bit fractional part) 10-19 Y-Component of Normal Vector (1bit sign + 9bit fractional part) 20-29 Z-Component of Normal Vector (1bit sign + 9bit fractional part) 30-31 Not used */ { Int64 xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = (xyz >> 0) & 0x3FF; if ((x & 0x200) != 0) x |= -1024; y = (xyz >> 10) & 0x3FF; if ((y & 0x200) != 0) y |= -1024; z = (xyz >> 20) & 0x3FF; if ((z & 0x200) != 0) z |= -1024; Gl.glNormal3f(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f); if (writevertex) { //normals.Add(new float[] { ((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f }); //mod.Normals.Add(new System.Windows.Media.Media3D.Vector3D(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f)) nor.Add(new System.Windows.Media.Media3D.Vector3D(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f)); } break; } case 0x22: /* Set Texture Coordinates (W) Parameter 1, Bit 0-15 S-Coordinate (X-Coordinate in Texture Source) Parameter 1, Bit 16-31 T-Coordinate (Y-Coordinate in Texture Source) Both values are 1bit sign + 11bit integer + 4bit fractional part. A value of 1.0 (=1 SHL 4) equals to one Texel. */ { Int64 st, s, t; st = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; s = (st >> 0) & 0xffff; if ((s & 0x8000) != 0) s |= unchecked((int)0xFFFF0000);//-65536; t = (st >> 16) & 0xffff; if ((t & 0x8000) != 0) t |= unchecked((int)0xFFFF0000);//-65536; Gl.glTexCoord2f(((float)s) / 16.0f, ((float)t) / 16.0f); if (writevertex) { //mod.TextureCoordinates.Add(new System.Windows.Point((float)s/1024f,(float)t/1024f)); tex.Add(new System.Windows.Point(((float)m.scaleS / (float)m.width) * ((float)s / 16f) / (m.flipS + 1), -((float)m.scaleT / (float)m.height) * ((float)t / 16f) / (m.flipT + 1))); } break; } case 0x23: /* VTX_16 - Set Vertex XYZ Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Y-Coordinate (signed, with 12bit fractional part) Parameter 2, Bit 0-15 Z-Coordinate (signed, with 12bit fractional part) Parameter 2, Bit 16-31 Not used */ { int parameter, x, y, z; parameter = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = sign((parameter >> 0) & 0xFFFF, 16); //if ((x & 0x8000) != 0) x |= unchecked((int)0xFFFF0000);//-65536; y = sign((parameter >> 16) & 0xFFFF, 16); //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536; parameter = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; z = sign(parameter & 0xFFFF, 16); // if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536; vtx_state[0] = ((float)x) / SCALE_IV; vtx_state[1] = ((float)y) / SCALE_IV; vtx_state[2] = ((float)z) / SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } if (writevertex) { //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x24: /* VTX_10 - Set Vertex XYZ Coordinates (W) Parameter 1, Bit 0-9 X-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 10-19 Y-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 20-29 Z-Coordinate (signed, with 6bit fractional part) Parameter 1, Bit 30-31 Not used */ { int xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = sign((xyz >> 0) & 0x3FF, 10); // if ((x & 0x200) != 0) x |= unchecked((int)0xFFFFFC00);//-1024; y = sign((xyz >> 10) & 0x3FF, 10); //if ((y & 0x200) != 0) y |= unchecked((int)0xFFFFFC00);//-1024; z = sign((xyz >> 20) & 0x3FF, 10); // if ((z & 0x200) != 0) z |= unchecked((int)0xFFFFFC00);//-1024; vtx_state[0] = (float)x / 64.0f; vtx_state[1] = (float)y / 64.0f; vtx_state[2] = (float)z / 64.0f; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } if (writevertex) { //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x25: /* VTX_XY - Set Vertex XY Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Y-Coordinate (signed, with 12bit fractional part) */ { int xy, x, y; xy = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = sign((xy >> 0) & 0xFFFF, 16); //if ((x & 0x8000) != 0) x |= unchecked((int)0xFFFF0000);//-65536; y = sign((xy >> 16) & 0xFFFF, 16); //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536; vtx_state[0] = ((float)x) / SCALE_IV; vtx_state[1] = ((float)y) / SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } if (writevertex) { //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x26: /* VTX_XZ - Set Vertex XZ Coordinates (W) Parameter 1, Bit 0-15 X-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Z-Coordinate (signed, with 12bit fractional part) */ { int xz, x, z; xz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = sign((xz >> 0) & 0xFFFF, 16); // if ((x & 0x8000) != 0) x |= unchecked((int)0xFFFF0000);//-65536; z = sign((xz >> 16) & 0xFFFF, 16); // if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536; vtx_state[0] = ((float)x) / SCALE_IV; vtx_state[2] = ((float)z) / SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } if (writevertex) { // vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x27: /* VTX_YZ - Set Vertex YZ Coordinates (W) Parameter 1, Bit 0-15 Y-Coordinate (signed, with 12bit fractional part) Parameter 1, Bit 16-31 Z-Coordinate (signed, with 12bit fractional part) */ { int yz, y, z; yz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; y = sign((yz >> 0) & 0xFFFF, 16); //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536; z = sign((yz >> 16) & 0xFFFF, 16); //if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536; vtx_state[1] = ((float)y) / SCALE_IV; vtx_state[2] = ((float)z) / SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } if (writevertex) { //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x28: /* VTX_DIFF - Set Relative Vertex Coordinates (W) Parameter 1, Bit 0-9 X-Difference (signed, with 9bit fractional part) Parameter 1, Bit 10-19 Y-Difference (signed, with 9bit fractional part) Parameter 1, Bit 20-29 Z-Difference (signed, with 9bit fractional part) Parameter 1, Bit 30-31 Not used */ { int xyz, x, y, z; xyz = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; x = sign((xyz >> 0) & 0x3FF, 10); //if ((x & 0x200) != 0) x |= unchecked((int)0xFFFFFC00);//-1024; y = sign((xyz >> 10) & 0x3FF, 10); //if ((y & 0x200) != 0) y |= unchecked((int)0xFFFFFC00); z = sign((xyz >> 20) & 0x3FF, 10); //if ((z & 0x200) != 0) z |= unchecked((int)0xFFFFFC00); vtx_state[0] += ((float)x) / SCALE_IV; vtx_state[1] += ((float)y) / SCALE_IV; vtx_state[2] += ((float)z) / SCALE_IV; if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); if (writevertex) { //vertex.Add(vtx_trans); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if (nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0)); } } } else { Gl.glVertex3fv(vtx_state); if (writevertex) { //vertex.Add(vtx_state); //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2])); if (poi.Count > tex.Count && tex.Count != 0) { tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } else if (tex.Count == 0) { tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity)); } if (poi.Count > nor.Count && nor.Count != 0) { nor.Add(nor[nor.Count - 1]); } else if(nor.Count == 0) { nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity,0)); } } } if (writevertex) { // vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count)); } break; } case 0x29: { int param = Utils.Read4BytesAsInt32(polydata, commandptr); commandptr += 4; /*int light = (param >> 0) & 0x10; int polygonMode = (param >> 4) & 0x4; switch (polygonMode) { case 0: mode = Gl.GL_MODULATE; break; case 1: mode = Gl.GL_DECAL; break; case 2: mode = Gl.GL_SHADOW_AMBIENT_SGIX; break; case 3: mode = Gl.GL_QUAD_STRIP; break; default: //return ;// FALSE; throw new Exception(); break; }*/ break; } case 0x2A: commandptr += 4; break; case 0x2B: commandptr += 4; break; // lighting commands case 0x30: commandptr += 4; break; case 0x31: commandptr += 4; break; case 0x32: commandptr += 4; break; case 0x33: { commandptr += 4; break; } case 0x34: commandptr += 128; break; case 0x40: // Start of Vertex List (W) { mode = Utils.Read4BytesAsInt32(polydata, commandptr); //mode = mode & 0x3; commandptr += 4; typ = mode; switch (mode) { case 0: mode = Gl.GL_TRIANGLES; break; case 1: mode = Gl.GL_QUADS; break; case 2: mode = Gl.GL_TRIANGLE_STRIP; break; case 3: mode = Gl.GL_QUAD_STRIP; break; default: //return ;// FALSE; throw new Exception(); break; } Gl.glBegin(mode); break; } case 0x41: // End of Vertex List (W) Gl.glEnd(); //mod.TriangleIndices.Add(nr); //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]); //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]); //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]); //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]); //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]); //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]); if (writevertex) { switch (typ) { case 0: { for (int j = 0; j < poi.Count / 3; j++) { //IList<System.Windows.Media.Media3D.Point3D> pol = new List<System.Windows.Media.Media3D.Point3D>(); //pol.Add(poi[j * 3]); //pol.Add(poi[j * 3 + 1]); //pol.Add(poi[j * 3 + 2]); /*IList<System.Windows.Media.Media3D.Vector3D> norm = new List<System.Windows.Media.Media3D.Vector3D>(); if (norm.Count > j + 1) { norm.Add(nor[j]); } IList<System.Windows.Point> text = new List<System.Windows.Point>(); if (tex.Count > j+1) { text.Add(tex[j]); }*/ //if (tex.Count > j + 1) //{ // md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2], tex[j], tex[j], tex[j]); //} //else if (tex.Count > j * 3 + 2) { md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2], tex[j * 3], tex[j * 3 + 1], tex[j * 3 + 2]); } else { md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2]); } } /*for (int j = 0; j < tex.Count; j++) { md[md.Count - 1].TextureCoordinates.Add(tex[j]); } for (int j = 0; j < nor.Count; j++) { md[md.Count - 1].Normals.Add(nor[j]); }*/ /*HelixToolkit.Mesh3D mb = new HelixToolkit.Mesh3D(); for (int j = 0; j < poi.Count; j += 3) { mb.Vertices.Add(poi[j]); mb.Vertices.Add(poi[j+1]); mb.Vertices.Add(poi[j+2]); mb.AddFace(new int[] { j, j + 1, j + 2 }); } HelixToolkit.MeshBuilder b = new HelixToolkit.MeshBuilder(); b.Append(mb.ToMeshGeometry3D()); //b.AddTriangles(poi, nor, tex); md[mo].Append(b);*/ break; } case 1: { for (int j = 0; j < poi.Count / 4; j++) { //IList<System.Windows.Media.Media3D.Point3D> pol = new List<System.Windows.Media.Media3D.Point3D>(); //pol.Add(poi[j * 4]); //pol.Add(poi[j * 4 + 1]); //pol.Add(poi[j * 4 + 2]); //pol.Add(poi[j * 4 + 3]); /*IList<System.Windows.Media.Media3D.Vector3D> norm = new List<System.Windows.Media.Media3D.Vector3D>(); if (norm.Count > j + 1) { norm.Add(nor[j]); } IList<System.Windows.Point> text = new List<System.Windows.Point>(); if (tex.Count > j + 1) { text.Add(tex[j]); } md[md.Count - 1].AddQuads(pol, norm, text);//.AddPolygon(pol);*/ //if (tex.Count > j + 1) //{ // md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3], tex[j], tex[j], tex[j], tex[j]); //} //else if (tex.Count > j * 4 + 3) { md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3], tex[j * 4], tex[j * 4 + 1], tex[j * 4 + 2], tex[j * 4 + 3]); } else { md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3]); } } /*for (int j = 0; j < tex.Count; j++) { md[md.Count - 1].TextureCoordinates.Add(tex[j]); } for (int j = 0; j < nor.Count; j++) { md[md.Count - 1].Normals.Add(nor[j]); }*/ /* HelixToolkit.Mesh3D mb = new HelixToolkit.Mesh3D(); for (int j = 0; j < poi.Count; j += 4) { mb.Vertices.Add(poi[j]); mb.Vertices.Add(poi[j + 1]); mb.Vertices.Add(poi[j + 2]); mb.Vertices.Add(poi[j + 3]); mb.AddFace(new int[] { j, j + 1, j + 2, j+3 }); } HelixToolkit.MeshBuilder b = new HelixToolkit.MeshBuilder(); b.Append(mb.ToMeshGeometry3D()); //b.AddTriangles(poi, nor, tex); md[mo].Append(b);*/ break; } case 2: { while (poi.Count > nor.Count) { nor.Add(nor[nor.Count - 1]); } while (poi.Count > tex.Count) { tex.Add(tex[tex.Count - 1]); } md[md.Count - 1].AddTriangles(poi, nor, tex); //md[mo].AddTriangleStrip(poi, nor, tex); break; } case 3: { while (poi.Count > nor.Count) { nor.Add(nor[nor.Count - 1]); } while (poi.Count > tex.Count) { tex.Add(tex[tex.Count - 1]); } md[md.Count - 1].AddQuads(poi, nor, tex); //md.AddQuads(poi, nor, tex); break; } default: //return ;// FALSE; break; } } nor.Clear(); tex.Clear(); poi.Clear(); //nr++; // for vertex mode, display at maximum certain number of vertex-list // decrease cur_vertex so that when we reach 0, stop rendering any further cur_vertex--; if (cur_vertex < 0 && gOptVertexMode) return; //TRUE; break; case 0x50: commandptr += 4; break; case 0x60: commandptr += 4; break; case 0x70: commandptr += 12; break; case 0x71: commandptr += 8; break; case 0x72: commandptr += 4; break; default: break; //return FALSE; } } } }
public static MTX44 mtx_Rotate(int pivot, int neg, float a, float b) { float[] data = new float[16]; data[15] = 1.0F; float one = 1.0F; float a2 = a; float b2 = b; switch (neg) { case 1: // '\001' case 3: // '\003' case 5: // '\005' case 7: // '\007' case 9: // '\t' case 11: // '\013' case 13: // '\r' case 15: // '\017' one = -1F; // fall through goto case 2; case 2: // '\002' case 4: // '\004' case 6: // '\006' case 8: // '\b' case 10: // '\n' case 12: // '\f' case 14: // '\016' default: switch (neg) { case 2: // '\002' case 3: // '\003' case 6: // '\006' case 7: // '\007' case 10: // '\n' case 11: // '\013' case 14: // '\016' case 15: // '\017' b2 = -b2; // fall through goto case 4; case 4: // '\004' case 5: // '\005' case 8: // '\b' case 9: // '\t' case 12: // '\f' case 13: // '\r' default: switch (neg) { case 4: // '\004' case 5: // '\005' case 6: // '\006' case 7: // '\007' case 12: // '\f' case 13: // '\r' case 14: // '\016' case 15: // '\017' a2 = -a2; // fall through goto case 8; case 8: // '\b' case 9: // '\t' case 10: // '\n' case 11: // '\013' default: switch (pivot) { case 0: // '\0' data[0] = one; data[5] = a; data[6] = b; data[9] = b2; data[10] = a2; break; case 1: // '\001' data[1] = one; data[4] = a; data[6] = b; data[8] = b2; data[10] = a2; break; case 2: // '\002' data[2] = one; data[4] = a; data[5] = b; data[8] = b2; data[9] = a2; break; case 3: // '\003' data[4] = one; data[1] = a; data[2] = b; data[9] = b2; data[10] = a2; break; case 4: // '\004' data[5] = one; data[0] = a; data[2] = b; data[8] = b2; data[10] = a2; break; case 5: // '\005' data[6] = one; data[0] = a; data[1] = b; data[8] = b2; data[9] = a2; break; case 6: // '\006' data[8] = one; data[1] = a; data[2] = b; data[5] = b2; data[6] = a2; break; case 7: // '\007' data[9] = one; data[0] = a; data[2] = b; data[4] = b2; data[6] = a2; break; case 8: // '\b' data[10] = one; data[0] = a; data[1] = b; data[4] = b2; data[5] = a2; break; case 9: // '\t' data[0] = -a; break; } break; } break; } break; } MTX44 matr = new MTX44(); matr._array = data; return matr; }
private MKDS_Course_Editor.Export3DTools.Group Process3DCommandRipper(byte[] polydata, NsbmdMaterial m, int jointID, bool color) { MKDS_Course_Editor.Export3DTools.Group group = new MKDS_Course_Editor.Export3DTools.Group(); Vector3 item = new Vector3(float.NaN, 0f, 0f); System.Drawing.Color white = System.Drawing.Color.White; Vector2 vector2 = new Vector2(float.NaN, 0f); List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); int num = -1; if (polydata != null) { int index = 0; int length = polydata.Length; int[] numArray = new int[4]; float[] numArray4 = new float[3]; float[] v = numArray4; numArray4 = new float[3]; float[] numArray3 = numArray4; int gCurrentVertex = NsbmdGlRenderer.gCurrentVertex; if (this.Model.Objects.Count > 0) { CurrentMatrix = MatrixStack[stackID].Clone(); } else { CurrentMatrix.LoadIdentity(); } if (this.Model.Objects.Count > 1) { } while (index < length) { int num7 = 0; while (num7 < 4) { if (index >= length) { numArray[num7] = 0xff; } else { numArray[num7] = polydata[index]; index++; } num7++; } for (num7 = 0; (num7 < 4) && (index < length); num7++) { int num6; int num8; int num9; int num10; MTX44 mtx; int num11; int num12; int num13; int num26; switch (numArray[num7]) { case 0x70: { index += 12; continue; } case 0x71: { index += 8; continue; } case 0x72: { index += 4; continue; } case 0x60: { index += 4; continue; } case 80: { index += 4; continue; } case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 0x1d: case 30: case 0x1f: case 0x2c: case 0x2d: case 0x2e: case 0x2f: case 0x11: { continue; } case 0x10: { num8 = Utils.Read4BytesAsInt32(polydata, index); index += 4; continue; } case 0x12: { index += 4; continue; } case 0x13: { index += 4; continue; } case 20: { stackID = Utils.Read4BytesAsInt32(polydata, index) & 0x1f; index += 4; MatrixStack[stackID].CopyValuesTo(CurrentMatrix); continue; } case 0x15: { CurrentMatrix.LoadIdentity(); continue; } case 0x16: { num9 = 0; while (num9 < 0x10) { CurrentMatrix[num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f; index += 4; num9++; } continue; } case 0x17: num9 = 0; goto Label_039C; case 0x18: mtx = new MTX44(); mtx.LoadIdentity(); num9 = 0; goto Label_03E8; case 0x19: mtx = new MTX44(); mtx.LoadIdentity(); num9 = 0; goto Label_0466; case 0x1a: mtx = new MTX44(); mtx.LoadIdentity(); num9 = 0; goto Label_04E3; case 0x1b: { num11 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num12 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num13 = Utils.Read4BytesAsInt32(polydata, index); index += 4; CurrentMatrix.Scale((((float)num11) / 4096f) / this.Model.modelScale, (((float)num12) / 4096f) / this.Model.modelScale, (((float)num13) / 4096f) / this.Model.modelScale); continue; } case 0x1c: { num11 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num12 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num13 = Utils.Read4BytesAsInt32(polydata, index); index += 4; CurrentMatrix.translate((((float)sign(num11, 0x20)) / 4096f) / this.Model.modelScale, (((float)sign(num12, 0x20)) / 4096f) / this.Model.modelScale, (((float)sign(num13, 0x20)) / 4096f) / this.Model.modelScale); continue; } case 0x20: { long num14 = Utils.Read4BytesAsInt32(polydata, index); index += 4; if (gOptColoring) { long num15 = num14 & 0x1fL; long num16 = (num14 >> 5) & 0x1fL; long num17 = (num14 >> 10) & 0x1fL; if (color) { white = System.Drawing.Color.FromArgb((int)(((float)m.Alpha) / 31f), (int)(((float)num15) / 31f), (int)(((float)num16) / 31f), (int)(((float)num17) / 31f)); } } continue; } case 0x21: { long num18 = Utils.Read4BytesAsInt32(polydata, index); index += 4; long num19 = num18 & 0x3ffL; if ((num19 & 0x200L) != 0L) { num19 |= -1024L; } long num20 = (num18 >> 10) & 0x3ffL; if ((num20 & 0x200L) != 0L) { num20 |= -1024L; } long num21 = (num18 >> 20) & 0x3ffL; if ((num21 & 0x200L) != 0L) { num21 |= -1024L; } item = new Vector3(((float)num19) / 512f, ((float)num20) / 512f, ((float)num21) / 512f); continue; } case 0x22: { long num22 = Utils.Read4BytesAsInt32(polydata, index); index += 4; long num23 = num22 & 0xffffL; if ((num23 & 0x8000L) != 0L) { num23 |= -65536L; } long num24 = (num22 >> 0x10) & 0xffffL; if ((num24 & 0x8000L) != 0L) { num24 |= -65536L; } vector2 = new Vector2(((m.scaleS / ((float)m.width)) * (((float)num23) / 16f)) / ((float)(m.flipS + 1)), (-(m.scaleT / ((float)m.height)) * (((float)num24) / 16f)) / ((float)(m.flipT + 1))); continue; } case 0x23: { int num25 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num11 = sign(num25 & 0xffff, 0x10); num12 = sign((num25 >> 0x10) & 0xffff, 0x10); num25 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num13 = sign(num25 & 0xffff, 0x10); v[0] = ((float)num11) / 4096f; v[1] = ((float)num12) / 4096f; v[2] = ((float)num13) / 4096f; if (stackID == -1) { goto Label_08E2; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_090F; } case 0x24: num26 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num11 = sign(num26 & 0x3ff, 10); num12 = sign((num26 >> 10) & 0x3ff, 10); num13 = sign((num26 >> 20) & 0x3ff, 10); v[0] = ((float)num11) / 64f; v[1] = ((float)num12) / 64f; v[2] = ((float)num13) / 64f; if (stackID == -1) { goto Label_09E1; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_0A0E; case 0x25: { int num27 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num11 = sign(num27 & 0xffff, 0x10); num12 = sign((num27 >> 0x10) & 0xffff, 0x10); v[0] = ((float)num11) / 4096f; v[1] = ((float)num12) / 4096f; if (stackID == -1) { goto Label_0ABF; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_0AEC; } case 0x26: { int num28 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num11 = sign(num28 & 0xffff, 0x10); num13 = sign((num28 >> 0x10) & 0xffff, 0x10); v[0] = ((float)num11) / 4096f; v[2] = ((float)num13) / 4096f; if (stackID == -1) { goto Label_0B9D; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_0BCA; } case 0x27: { int num29 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num12 = sign(num29 & 0xffff, 0x10); num13 = sign((num29 >> 0x10) & 0xffff, 0x10); v[1] = ((float)num12) / 4096f; v[2] = ((float)num13) / 4096f; if (stackID == -1) { goto Label_0C7B; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_0CA8; } case 40: num26 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num11 = sign(num26 & 0x3ff, 10); num12 = sign((num26 >> 10) & 0x3ff, 10); num13 = sign((num26 >> 20) & 0x3ff, 10); v[0] += ((float)num11) / 4096f; v[1] += ((float)num12) / 4096f; v[2] += ((float)num13) / 4096f; if (stackID == -1) { goto Label_0DAA; } numArray3 = CurrentMatrix.MultVector(v); list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2])); list2.Add(item); list3.Add(vector2); goto Label_0DD7; case 0x29: { num8 = Utils.Read4BytesAsInt32(polydata, index); index += 4; continue; } case 0x2a: { index += 4; continue; } case 0x2b: { index += 4; continue; } case 0x30: { index += 4; continue; } case 0x31: { index += 4; continue; } case 50: { index += 4; continue; } case 0x33: { index += 4; continue; } case 0x34: { index += 0x80; continue; } case 0x40: num6 = Utils.Read4BytesAsInt32(polydata, index); index += 4; num = num6; switch (num6) { case 0: goto Label_0E92; case 1: goto Label_0E97; case 2: goto Label_0E9C; case 3: goto Label_0EA1; } throw new Exception(); case 0x41: switch (num) { case 0: goto Label_0ED1; case 1: goto Label_0EF6; case 2: goto Label_0F1B; case 3: goto Label_0F40; } goto Label_0F67; default: { continue; } } Label_0358: num10 = 0; while (num10 < 3) { CurrentMatrix[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f; index += 4; num9++; } num9++; Label_039C: if (num9 < 4) { goto Label_0358; } continue; Label_03C1: mtx[num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f; index += 4; num9++; Label_03E8: if (num9 < 0x10) { goto Label_03C1; } CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix); continue; Label_0425: num10 = 0; while (num10 < 3) { mtx[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f; index += 4; num9++; } num9++; Label_0466: if (num9 < 4) { goto Label_0425; } CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix); continue; Label_04A2: num10 = 0; while (num10 < 3) { mtx[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f; index += 4; num9++; } num9++; Label_04E3: if (num9 < 3) { goto Label_04A2; } CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix); continue; Label_08E2: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_090F: if (this.writevertex) { } continue; Label_09E1: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_0A0E: if (this.writevertex) { } continue; Label_0ABF: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_0AEC: if (this.writevertex) { } continue; Label_0B9D: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_0BCA: if (this.writevertex) { } continue; Label_0C7B: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_0CA8: if (this.writevertex) { } continue; Label_0DAA: list.Add(new Vector3(v[0], v[1], v[2])); list2.Add(item); list3.Add(vector2); Label_0DD7: if (this.writevertex) { } continue; Label_0E92: num6 = 4; continue; Label_0E97: num6 = 7; continue; Label_0E9C: num6 = 5; continue; Label_0EA1: num6 = 8; continue; Label_0ED1: group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.Triangle, list2.ToArray(), list3.ToArray(), list.ToArray())); goto Label_0F67; Label_0EF6: group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.Quad, list2.ToArray(), list3.ToArray(), list.ToArray())); goto Label_0F67; Label_0F1B: group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.TriangleStrip, list2.ToArray(), list3.ToArray(), list.ToArray())); goto Label_0F67; Label_0F40: group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.QuadStrip, list2.ToArray(), list3.ToArray(), list.ToArray())); Label_0F67: list2.Clear(); list.Clear(); list3.Clear(); gCurrentVertex--; if ((gCurrentVertex < 0) && gOptVertexMode) { return group; } } } } return group; }