private void reactionNormal(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter) { /* * 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 */ actualCommand = poly.commandList[blockCounter + idCounter]; actualCommand.par = reader.ReadInt32(); actualCommand.x = (actualCommand.par >> 0) & 0x3FF; if ((actualCommand.x & 0x200) != 0) { actualCommand.x |= -1024; } actualCommand.y = (actualCommand.par >> 10) & 0x3FF; if ((actualCommand.y & 0x200) != 0) { actualCommand.y |= -1024; } actualCommand.z = (actualCommand.par >> 20) & 0x3FF; if ((actualCommand.z & 0x200) != 0) { actualCommand.z |= -1024; } Gl.glPushName((int)actualCommand.startParameterOffset); Gl.glNormal3f(((float)actualCommand.x) / 512.0f, ((float)actualCommand.y) / 512.0f, ((float)actualCommand.z) / 512.0f); Gl.glPopName(); poly.commandList[blockCounter + idCounter] = actualCommand; }
private static void reactionBegin(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter) { int mode; actualCommand.par = reader.ReadInt32(); mode = actualCommand.par; actualCommand.id = 0x40; actualCommand.x = -1; 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; } Gl.glBegin(mode); poly.commandList[blockCounter + idCounter] = actualCommand; }
private void reactionTextureCoordinate(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter) { /* * 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. */ { actualCommand = poly.commandList[blockCounter + idCounter]; actualCommand.par = reader.ReadInt32(); actualCommand.x = (actualCommand.par >> 0) & 0xffff; if ((actualCommand.x & 0x8000) != 0) { actualCommand.x |= -65536; } actualCommand.y = (actualCommand.par >> 16) & 0xffff; if ((actualCommand.y & 0x8000) != 0) { actualCommand.y |= -65536; } Gl.glPushName((int)actualCommand.startParameterOffset); Gl.glTexCoord2f(((float)actualCommand.x) / 16.0f, ((float)actualCommand.y) / 16.0f); poly.commandList[blockCounter + idCounter] = actualCommand; } }
public NsbmdModel.ShapeInfoStruct process3DCommand(byte[] polydata, NsbmdModel.ShapeInfoStruct poly) { if (polydata == null) { return(poly); } else { MemoryStream polyStream = new MemoryStream(); polyStream.Write(polydata, 0, polydata.Length); var reader = new BinaryReader(polyStream); reader.BaseStream.Position = 0; var actualCommand = new NsbmdModel.CommandStruct(); poly.commandList = new List <NsbmdModel.CommandStruct>(); int cur_vertex, idCounter; int blockCounter = 0; 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 (reader.BaseStream.Position < polyStream.Length) { idCounter = initId(ref poly, polyStream, reader); renderPackedCommand(ref poly, polyStream, reader, ref actualCommand, ref cur_vertex, ref idCounter, ref blockCounter, vtx_state, ref vtx_trans); } return(poly); } }
private void reactionColor(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter) { actualCommand = poly.commandList[blockCounter + idCounter]; actualCommand.par = reader.ReadInt32(); actualCommand.x = (actualCommand.par >> 0) & 0x1F; actualCommand.y = (actualCommand.par >> 5) & 0x1F; actualCommand.z = (actualCommand.par >> 10) & 0x1F; Gl.glColor3f(((float)actualCommand.x) / 31.0f, ((float)actualCommand.y) / 31.0f, ((float)actualCommand.z) / 31.0f); Gl.glColor3f(1, 1, 1); poly.commandList[blockCounter + idCounter] = actualCommand; }
private void reactionVtx_16(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter, float[] vtx_state, ref float[] vtx_trans) { /* * 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 */ { actualCommand = poly.commandList[blockCounter + idCounter]; actualCommand.par = reader.ReadInt32(); actualCommand.x = (actualCommand.par >> 0) & 0xFFFF; if ((actualCommand.x & 0x8000) != 0) { actualCommand.x |= -65536; } actualCommand.y = (actualCommand.par >> 16) & 0xFFFF; if ((actualCommand.y & 0x8000) != 0) { actualCommand.y |= -65536; } actualCommand.par2 = reader.ReadInt32(); actualCommand.z = actualCommand.par2 & 0xFFFF; if ((actualCommand.z & 0x8000) != 0) { actualCommand.z |= -65536; } xBuffer = actualCommand.x; yBuffer = actualCommand.y; zBuffer = actualCommand.z; vtx_state[0] = ((float)actualCommand.x) / SCALE_IV; vtx_state[1] = ((float)actualCommand.y) / SCALE_IV; vtx_state[2] = ((float)actualCommand.z) / SCALE_IV; Gl.glPushName((int)actualCommand.startParameterOffset); if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } poly.commandList[blockCounter + idCounter] = actualCommand; } }
private void reactionMatrixScale(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter) { /* * 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) */ actualCommand = poly.commandList[blockCounter + idCounter]; actualCommand.x = reader.ReadInt32(); actualCommand.y = reader.ReadInt32(); actualCommand.z = reader.ReadInt32(); CurrentMatrix.Scale(actualCommand.x / SCALE_IV, actualCommand.y / SCALE_IV, actualCommand.z / SCALE_IV); poly.commandList[blockCounter + idCounter] = actualCommand; }
private void reactionVtx_Diff(ref NsbmdModel.ShapeInfoStruct poly, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, int idCounter, int blockCounter, float[] vtx_state, ref float[] vtx_trans) { /* * 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 */ { actualCommand.id = 0x28; actualCommand.par = reader.ReadInt32(); actualCommand.x = (actualCommand.par >> 0) & 0x3FF; if ((actualCommand.x & 0x200) != 0) { actualCommand.x |= -1024; } actualCommand.y = (actualCommand.par >> 10) & 0x3FF; if ((actualCommand.y & 0x200) != 0) { actualCommand.y |= -1024; } actualCommand.z = (actualCommand.par >> 20) & 0x3FF; if ((actualCommand.z & 0x200) != 0) { actualCommand.z |= -1024; } xBuffer = actualCommand.x; yBuffer = actualCommand.y; zBuffer = actualCommand.z; vtx_state[0] += ((float)actualCommand.x) / SCALE_IV; vtx_state[1] += ((float)actualCommand.y) / SCALE_IV; vtx_state[2] += ((float)actualCommand.z) / SCALE_IV; Gl.glPushName((int)actualCommand.startParameterOffset); if (stackID != -1) { vtx_trans = CurrentMatrix.MultVector(vtx_state); Gl.glVertex3fv(vtx_trans); } else { Gl.glVertex3fv(vtx_state); } poly.commandList[blockCounter + idCounter] = actualCommand; } }
private void processObjects(int idActualPol, int isTextured, ref NsbmdModel.ShapeInfoStruct actualPolygon, ref NsbmdModel.MatTexPalStruct actualMaterials, int num_obj, int idActualMateria) { NsbmdModel.NodeInfoStruct actualNodeInfo = modelList[idModel].getMDL0at(0).nodeInfoList[num_obj]; if (actualNodeInfo.restoreId != -1) { Gl.glLoadMatrixf(MatrixStack[actualNodeInfo.restoreId].Floats); } if (actualNodeInfo.stackId != -1) { Gl.glGetFloatv(Gl.GL_MODELVIEW_MATRIX, MatrixStack[actualNodeInfo.stackId].Floats); stackID = actualNodeInfo.stackId; } Gl.glLoadIdentity(); actualPolygon = modelList[idModel].getMDL0at(0).shapeInfo.shapeList[idActualPol]; var actualMaterial = modelList[idModel].getMaterials()[idActualMaterial]; if (isTextured == 0) { Gl.glPolygonMode(0x408, 0x1b01); } else { Gl.glPolygonMode(0x408, 0x1b02); } Gl.glBindTexture(Gl.GL_TEXTURE_2D, idActualMaterial + 1); Gl.glMatrixMode(Gl.GL_TEXTURE); Gl.glLoadIdentity(); if ((actualMaterials.flipS == 1) && (actualMaterials.repeatS > 0)) { Gl.glScalef(2f / ((float)actualMaterials.width), 1f / ((float)actualMaterials.heigth), 1f); } else if ((actualMaterials.flipT == 1) && (actualMaterials.repeatT > 0)) { Gl.glScalef(1f / ((float)actualMaterials.width), 2f / ((float)actualMaterials.heigth), 1f); } else { Gl.glScalef(1f / ((float)actualMaterials.width), 1f / ((float)actualMaterials.heigth), 1f); } Gl.glColor3f(1f, 1f, 1f); stackID = actualPolygon.stackId; modelList[idModel].getMDL0at(0).shapeInfo.shapeList[idActualPol] = process3DCommand(actualPolygon.polygonData, actualPolygon); }
private static int initId(ref NsbmdModel.ShapeInfoStruct poly, MemoryStream polyStream, BinaryReader reader) { int idCounter; idCounter = 0; while (idCounter < 4) { if (reader.BaseStream.Position < polyStream.Length) { poly.commandList.Add(new NsbmdModel.CommandStruct() { id = reader.ReadByte(), startIdOffset = reader.BaseStream.Position }); } idCounter++; } return(idCounter); }
private void renderPackedCommand(ref NsbmdModel.ShapeInfoStruct poly, MemoryStream polyStream, BinaryReader reader, ref NsbmdModel.CommandStruct actualCommand, ref int cur_vertex, ref int idCounter, ref int blockCounter, float[] vtx_state, ref float[] vtx_trans) { for (idCounter = 0; idCounter < 4 && reader.BaseStream.Position < polyStream.Length; idCounter++) { switch (poly.commandList[blockCounter + idCounter].id) { case 0: // No Operation (for padding packed GXFIFO commands) break; case 0x14: reactionMatrixRestore(reader); break; case 0x1b: reactionMatrixScale(ref poly, reader, ref actualCommand, idCounter, blockCounter); break; case 0x20: // Directly Set Vertex Color (W) reactionColor(ref poly, reader, ref actualCommand, idCounter, blockCounter); break; case 0x21: reactionNormal(ref poly, reader, ref actualCommand, idCounter, blockCounter); break; case 0x22: reactionTextureCoordinate(ref poly, reader, ref actualCommand, idCounter, blockCounter); break; case 0x23: reactionVtx_16(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x24: reactionVtx_10(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x25: reactionVtx_XY(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x26: reactionVtx_XZ(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x27: reactionVtx_YZ(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x28: reactionVtx_Diff(ref poly, reader, ref actualCommand, idCounter, blockCounter, vtx_state, ref vtx_trans); break; case 0x40: // Start of Vertex List (W) reactionBegin(ref poly, reader, ref actualCommand, idCounter, blockCounter); break; case 0x41: // End of Vertex List (W) Gl.glEnd(); cur_vertex--; break; default: break; } if (idCounter == 3) { blockCounter += 4; } } }