private static void WritePolygon(StreamWriter writer, MDL0PolygonNode poly) { if (poly._vertexNode != null) { WriteVertexGroup(writer, poly._vertexNode); } if (poly._normalNode != null) { WriteNormalGroup(writer, poly._normalNode); } if (poly._uvSet[0] != null) { WriteUVGroup(writer, poly._uvSet[0]); } writer.WriteLine(); writer.WriteLine(String.Format("g {0}", poly.Name)); if (poly._material != null) { WriteMaterial(writer, poly._material); } foreach (Primitive p in poly.Primitives) { switch (p._type) { //case GLPrimitiveType.TriangleFan: WriteTriFan(writer, p); break; //case GLPrimitiveType.TriangleStrip: WriteTriStrip(writer, p); break; case GLPrimitiveType.Triangles: WriteTriList(writer, p); break; //case GLPrimitiveType.Quads: WriteQuadList(writer, p); break; } } }
private void lstPolygons_SelectedValueChanged(object sender, EventArgs e) { _targetObject = _selectedPolygon = lstPolygons.SelectedItem as MDL0PolygonNode; if (SelectedPolygonChanged != null) { SelectedPolygonChanged(this, null); } }
private void MergeChildren(MDL0BoneNode main, MDL0BoneNode ext, ResourceNode res) { bool found = false; if (res is MDL0PolygonNode) { MDL0PolygonNode poly = res as MDL0PolygonNode; foreach (Vertex3 v in poly._manager._vertices) { if (v._influence == ext) { v._influence = main; main.ReferenceCount++; } } } else if (res is MDL0Node) { MDL0Node mdl = res as MDL0Node; foreach (MDL0PolygonNode poly in mdl.FindChild("Objects", true).Children) { foreach (Vertex3 v in poly._manager._vertices) { if (v._influence == ext) { v._influence = main; main.ReferenceCount++; } } } } foreach (MDL0BoneNode b2 in ext.Children) { foreach (MDL0BoneNode b1 in main.Children) { if (b1.Name == b2.Name) { found = true; MergeChildren(b1, b2, res); break; } } if (!found) { if (b2.ReferenceCount > 0) { main.InsertChild(b2, true, b2.Index); } } else { found = false; } } }
private static void SetFormatLists(ModelLinker linker) { if (linker.Model._polyList != null) { for (int i = 0; i < linker.Model._polyList.Count; i++) { MDL0PolygonNode poly = (MDL0PolygonNode)linker.Model._polyList[i]; poly._fmtList = poly._manager.setFmtList(poly, linker); } } }
private void getBaseInfluence() { ResourceNode[] boneCache = _externalModel._linker.BoneCache; if ((node = (MDL0PolygonNode)comboBox1.SelectedItem).Weighted) { int least = int.MaxValue; foreach (IMatrixNode inf in node.Influences) { if (inf is MDL0BoneNode && ((MDL0BoneNode)inf).BoneIndex < least) { least = ((MDL0BoneNode)inf).BoneIndex; } } if (least != int.MaxValue) { MDL0BoneNode temp = (MDL0BoneNode)boneCache[least]; _baseInf = (IMatrixNode)temp.Parent; } } else { _baseInf = node.SingleBindInf; } if (_baseInf is Influence) { label2.Hide(); comboBox2.Hide(); } else if (_baseInf is MDL0BoneNode) { label2.Show(); comboBox2.Show(); } switch (comboBox3.SelectedIndex) { case 0: label2.Text = "Add base bone \"" + _baseInf + "\" to the children of: "; break; case 1: label2.Text = "With base bone \"" + _baseInf + "\", replace: "; break; case 2: label2.Text = "Merge base bone \"" + _baseInf + "\" with: "; break; } comboBox2.Location = new Drawing.Point(label2.Size.Width + 20, 36); //Width = comboBox2.Location.X + 140; }
private void lstPolygons_ItemCheck(object sender, ItemCheckEventArgs e) { MDL0PolygonNode poly = lstPolygons.Items[e.Index] as MDL0PolygonNode; poly._render = e.NewValue == CheckState.Checked; if (_syncVis0 && poly._bone != null) { bool temp = false; if (!_vis0Updating) { _vis0Updating = true; temp = true; } if (VIS0Indices.ContainsKey(poly._bone.Name)) { foreach (int i in VIS0Indices[poly._bone.Name]) { if (((MDL0PolygonNode)lstPolygons.Items[i])._render != poly._render) { lstPolygons.SetItemChecked(i, poly._render); } } } if (temp) { _vis0Updating = false; temp = false; } if (!_vis0Updating) { _polyIndex = e.Index; if (Vis0Updated != null) { Vis0Updated(this, null); } } } if (!_updating) { if (RenderStateChanged != null) { RenderStateChanged(this, null); } } }
private void lstPolygons_ItemCheck(object sender, ItemCheckEventArgs e) { MDL0PolygonNode poly = lstPolygons.Items[e.Index] as MDL0PolygonNode; poly._render = e.NewValue == CheckState.Checked; if (!_updating) { if (RenderStateChanged != null) { RenderStateChanged(this, null); } } }
public void Attach(MDL0Node model) { lstPolygons.BeginUpdate(); lstPolygons.Items.Clear(); lstBones.BeginUpdate(); lstBones.Items.Clear(); lstTextures.BeginUpdate(); lstTextures.Items.Clear(); _selectedBone = null; _selectedPolygon = null; _targetObject = null; chkAllPoly.CheckState = CheckState.Checked; chkAllBones.CheckState = CheckState.Checked; chkAllTextures.CheckState = CheckState.Checked; if (model != null) { ResourceNode n; if ((n = model.FindChild("Polygons", false)) != null) { foreach (MDL0PolygonNode poly in n.Children) { lstPolygons.Items.Add(poly, poly._render); } } if ((n = model.FindChild("Bones", false)) != null) { foreach (MDL0BoneNode bone in n.Children) { WrapBone(bone); } } if ((n = model.FindChild("Textures", false)) != null) { foreach (MDL0TextureNode tref in n.Children) { lstTextures.Items.Add(tref, tref.Enabled); } } } lstTextures.EndUpdate(); lstPolygons.EndUpdate(); lstBones.EndUpdate(); }
private static void WritePolyInstance(MDL0PolygonNode poly, XmlWriter writer) { writer.WriteStartElement("node"); writer.WriteAttributeString("id", poly.Name); writer.WriteAttributeString("name", poly.Name); if (poly._singleBind != null) { //Doesn't create a skin modifier, but works writer.WriteStartElement("instance_geometry"); writer.WriteAttributeString("url", String.Format("#{0}", poly.Name)); } else { writer.WriteStartElement("instance_controller"); writer.WriteAttributeString("url", String.Format("#{0}_Controller", poly.Name)); } //writer.WriteStartElement("skeleton"); //writer.WriteString("#" + poly.Model._linker.BoneCache[0].Name); //writer.WriteEndElement(); if (poly._material != null) { writer.WriteStartElement("bind_material"); writer.WriteStartElement("technique_common"); writer.WriteStartElement("instance_material"); writer.WriteAttributeString("symbol", poly._material.Name); writer.WriteAttributeString("target", "#" + poly._material.Name); foreach (MDL0MaterialRefNode mr in poly._material.Children) { writer.WriteStartElement("bind_vertex_input"); writer.WriteAttributeString("semantic", "TEXCOORD" + (mr.TextureCoordId < 0 ? 0 : mr.TextureCoordId)); //Replace with true set id writer.WriteAttributeString("input_semantic", "TEXCOORD"); writer.WriteAttributeString("input_set", (mr.TextureCoordId < 0 ? 0 : mr.TextureCoordId).ToString()); //Replace with true set id writer.WriteEndElement(); //bind_vertex_input break; //Only one texture reference allowed, it seems. } writer.WriteEndElement(); //instance_material writer.WriteEndElement(); //technique_common writer.WriteEndElement(); //bind_material } writer.WriteEndElement(); //instance_geometry writer.WriteEndElement(); //node }
private static void WritePolyInstance(MDL0PolygonNode poly, XmlWriter writer) { writer.WriteStartElement("node"); writer.WriteAttributeString("id", poly.Name); writer.WriteAttributeString("name", poly.Name); //if (poly._singleBind != null) //{ //writer.WriteStartElement("instance_geometry"); //writer.WriteAttributeString("url", "#" + poly.Name); //} //else //{ writer.WriteStartElement("instance_controller"); writer.WriteAttributeString("url", String.Format("#{0}_Controller", poly.Name)); //} if (poly._material != null) { writer.WriteStartElement("bind_material"); writer.WriteStartElement("technique_common"); writer.WriteStartElement("instance_material"); writer.WriteAttributeString("symbol", poly._material.Name); writer.WriteAttributeString("target", "#" + poly._material.Name); foreach (MDL0MaterialRefNode mr in poly._material._children) { writer.WriteStartElement("bind_vertex_input"); writer.WriteAttributeString("semantic", "TEXCOORD0"); //Replace with true set id writer.WriteAttributeString("input_semantic", "TEXCOORD"); writer.WriteAttributeString("input_set", "0"); //Replace with true set id writer.WriteEndElement(); //bind_vertex_input break; } writer.WriteEndElement(); //instance_material writer.WriteEndElement(); //technique_common writer.WriteEndElement(); //bind_material } writer.WriteEndElement(); //instance_geometry writer.WriteEndElement(); //node }
public void Attach(MDL0Node model) { lstPolygons.BeginUpdate(); lstPolygons.Items.Clear(); lstBones.BeginUpdate(); lstBones.Items.Clear(); lstTextures.BeginUpdate(); lstTextures.Items.Clear(); _selectedBone = null; _selectedPolygon = null; _targetObject = null; chkAllPoly.CheckState = CheckState.Checked; chkAllBones.CheckState = CheckState.Checked; chkAllTextures.CheckState = CheckState.Checked; if (model != null) { ResourceNode n; if ((n = model.FindChild("Objects", false)) != null) { foreach (MDL0PolygonNode poly in n.Children) { lstPolygons.Items.Add(poly, poly._render); } } if ((n = model.FindChild("Bones", false)) != null) { foreach (MDL0BoneNode bone in n.Children) { WrapBone(bone); } } if ((n = model.FindChild("Textures", false)) != null) { foreach (MDL0TextureNode tref in n.Children) { lstTextures.Items.Add(tref, tref.Enabled); } } } lstTextures.EndUpdate(); lstPolygons.EndUpdate(); lstBones.EndUpdate(); VIS0Indices.Clear(); int i = 0; foreach (MDL0PolygonNode p in lstPolygons.Items) { if (p._bone != null && p._bone.BoneIndex != 0) { if (VIS0Indices.ContainsKey(p._bone.Name)) { if (!VIS0Indices[p._bone.Name].Contains(i)) { VIS0Indices[p._bone.Name].Add(i); } } else { VIS0Indices.Add(p._bone.Name, new List <int> { i }); } } i++; } }
public static int CalcSize(Collada form, ModelLinker linker) { MDL0Node model = linker.Model; int headerLen, groupLen = 0, tableLen = 0, texLen = 0, boneLen = 0, dataLen = 0, defLen = 0, assetLen = 0, treeLen = 0, mixLen = 0, opaLen = 0, xluLen = 0; int aInd, aLen; //Get header length switch (linker.Version) { case 0x08: case 0x09: headerLen = 0x80; break; case 0x0A: headerLen = 0x88; break; case 0x0B: headerLen = 0x8C; break; default: headerLen = 0x80; //Unsupported version. Change to 9 as default. linker.Version = 9; break; } //Assign node indices AssignNodeIndices(linker); //Get table length tableLen = (linker._nodeCount + 1) << 2; //Get group/data length List <MDLResourceType> iList = ModelLinker.IndexBank[linker.Version]; foreach (MDLResourceType resType in iList) { IEnumerable entryList = null; int entries = 0; switch (resType) { case MDLResourceType.Definitions: //NodeTree treeLen = linker.BoneCache.Length * 5; //NodeMix foreach (Influence i in model._influences._influences) { mixLen += 4; foreach (BoneWeight w in i._weights) { mixLen += 6; } } foreach (MDL0BoneNode b in linker.BoneCache) { if (b._weightCount > 0) { mixLen += 5; } } //DrawOpa and DrawXlu //Get assigned materials and categorize if (model._matList != null) { for (int i = 0; i < model._matList.Count; i++) { //Entries are ordered by material, not by polygon. MDL0MaterialNode mat = model._matList[i] as MDL0MaterialNode; if (!mat.isMetal) { for (int l = 0; l < mat._polygons.Count; l++) { if (!mat.XLUMaterial) { opaLen += 8; } else { xluLen += 8; } } } } } //Add terminate byte and set model def flags if (model._hasTree = (treeLen > 0)) { treeLen++; entries++; } if (model._hasMix = (mixLen > 0)) { mixLen++; entries++; } if (model._hasOpa = (opaLen > 0)) { opaLen++; entries++; } if (model._hasXlu = (xluLen > 0)) { xluLen++; entries++; } //Align data defLen += (treeLen + mixLen + opaLen + xluLen).Align(4); break; case MDLResourceType.Vertices: if (model._vertList != null) { entryList = model._vertList; break; } else { aInd = 0; //Set the ID aLen = 1; //Offset count } EvalAssets: List <ResourceNode> polyList = model._polyList; if (polyList == null) { break; } string str = ""; //Create asset lists IList aList; switch (aInd) //Switch by the set ID { case 0: aList = linker._vertices = new List <VertexCodec>(polyList.Count); str = "Vertices "; break; case 1: aList = linker._normals = new List <VertexCodec>(polyList.Count); str = "Normals "; break; case 2: aList = linker._colors = new List <ColorCodec>(polyList.Count); str = "Colors "; break; default: aList = linker._uvs = new List <VertexCodec>(polyList.Count); str = "UVs "; break; } aLen += aInd; for (int i = 0; i < polyList.Count; i++) { MDL0PolygonNode p = polyList[i] as MDL0PolygonNode; for (int x = aInd; x < aLen; x++) { if (p._manager._faceData[x] != null) { if (model._importOptions._rmpClrs && model._importOptions._addClrs) { if (i > 0 && x == 2 && model._noColors == true) { p._elementIndices[x] = 0; continue; } else if (i >= 0 && x == 3 && model._noColors == true) { p._elementIndices[x] = -1; break; } } p._elementIndices[x] = (short)aList.Count; if (form != null) { form.Say("Encoding " + str + (x - aInd) + " for Object " + i + ": " + p.Name); } switch (aInd) { case 0: VertexCodec vert; aList.Add(vert = new VertexCodec(p._manager.RawVertices, false, model._importOptions._fltVerts)); assetLen += vert._dataLen.Align(0x20) + 0x40; break; case 1: aList.Add(vert = new VertexCodec(p._manager.RawNormals, false, model._importOptions._fltNrms)); assetLen += vert._dataLen.Align(0x20) + 0x20; break; case 2: ColorCodec col; aList.Add(col = new ColorCodec(p._manager.Colors(x - 2))); assetLen += col._dataLen.Align(0x20) + 0x20; break; default: aList.Add(vert = new VertexCodec(p._manager.UVs(x - 4), model._importOptions._fltUVs)); assetLen += vert._dataLen.Align(0x20) + 0x40; break; } } else { p._elementIndices[x] = -1; } } } entries = aList.Count; break; case MDLResourceType.Normals: if (model._normList != null) { entryList = model._normList; } else { aInd = 1; //Set the ID aLen = 1; //Offset count goto EvalAssets; } break; case MDLResourceType.Colors: if (model._colorList != null) { entryList = model._colorList; } else { aInd = 2; //Set the ID aLen = 2; //Offset count goto EvalAssets; } break; case MDLResourceType.UVs: if (model._uvList != null) { entryList = model._uvList; } else { aInd = 4; //Set the ID aLen = 8; //Offset count goto EvalAssets; } break; case MDLResourceType.Bones: int index = 0; foreach (MDL0BoneNode b in linker.BoneCache) { if (form != null) { form.Say("Calculating the size of the Bones - " + b.Name); } b._entryIndex = index++; boneLen += b.CalculateSize(true); } entries = linker.BoneCache.Length; break; case MDLResourceType.Materials: if (model._matList != null) { entries = model._matList.Count; } break; case MDLResourceType.Objects: if (model._polyList != null) { entryList = model._polyList; } break; case MDLResourceType.Shaders: if ((entryList = model.GetUsedShaders()) != null && model._matList != null) { entries = model._matList.Count; } break; case MDLResourceType.Textures: if (model._texList != null) { foreach (MDL0TextureNode tex in model._texList) { texLen += (tex._references.Count * 8) + 4; } linker._texCount = entries = model._texList.Count; } break; case MDLResourceType.Palettes: if (model._pltList != null) { foreach (MDL0TextureNode pal in model._pltList) { texLen += (pal._references.Count * 8) + 4; } linker._palCount = entries = model._pltList.Count; } break; } if (entryList != null) { int index = 0; foreach (MDL0EntryNode e in entryList) { if (form != null) { if (resType == MDLResourceType.Objects) { form.Say("Encoding the " + resType.ToString() + " - " + e.Name); } else { form.Say("Calculating the size of the " + resType.ToString() + " - " + e.Name); } } e._entryIndex = index++; dataLen += e.CalculateSize(true); } if (entries == 0) { entries = index; } } if (entries > 0) { groupLen += (entries * 0x10) + 0x18; } } //Align the materials perfectly using the data length int temp = 0; if (model._matList != null && iList.IndexOf(MDLResourceType.Materials) != -1) { int index = 0; MDL0MaterialNode prev = null; foreach (MDL0MaterialNode e in model._matList) { if (form != null) { form.Say("Calculating the size of the Materials - " + e.Name); } e._entryIndex = index++; if (index == 1) { if ((temp = (e._mdlOffset = headerLen + tableLen + groupLen + texLen + defLen + boneLen).Align(0x10)) != e._mdlOffset) { e._dataAlign = temp - e._mdlOffset; } } else { e._mdlOffset = (prev = ((MDL0MaterialNode)model._matList[index - 1]))._mdlOffset + prev._calcSize; } dataLen += e.CalculateSize(true); } } return ((linker._headerLen = headerLen) + (linker._tableLen = tableLen) + (linker._groupLen = groupLen) + (linker._texLen = texLen) + (linker._defLen = defLen) + (linker._boneLen = boneLen) + (linker._assetLen = assetLen) + (linker._dataLen = dataLen) + (model._part2Entries.Count > 0 ? 0x1C + model._part2Entries.Count * 0x2C : 0)); }
public static int CalcSize(ModelLinker linker) { MDL0Node model = linker.Model; int headerLen, groupLen = 0x18, tableLen = 0, texLen = 0, dataLen = 0; int treeLen = 0, mixLen = 0, opaLen = 0, xluLen = 0; int texCount = 0, decCount = 0; int aInd, aLen, temp; //Get header length switch (linker.Version) { case 0x09: headerLen = 0x80; break; default: headerLen = 0; break; } //Assign node indices AssignNodeIndices(linker); //Get table length tableLen = (linker._nodeCount + 1) << 2; //Get group/data length List <MDLResourceType> iList = ModelLinker.IndexBank[linker.Version]; foreach (MDLResourceType resType in iList) { IEnumerable entryList = null; int entries = 0; //entries = 0; switch (resType) { case MDLResourceType.Defs: { //NodeTree treeLen = linker.BoneCache.Length * 5; //NodeMix foreach (IMatrixNode i in linker.NodeCache) { if (!i.IsPrimaryNode) { mixLen += ((Influence)i)._weights.Length * 8 + 4; } else if (i.ReferenceCount > 0) { mixLen += 5; } } //DrawOpa, DrawXlu //Get assigned materials and categorize foreach (MDL0PolygonNode poly in linker.Model.PolygonList) { if (poly._material == null) { continue; } //Is material transparent? if (poly._material.EnableBlend) { opaLen += 8; } else { xluLen += 8; } } //Add terminate byte and set model def flags if (linker.Model._hasTree = (treeLen > 0)) { treeLen++; entries++; } if (linker.Model._hasMix = (mixLen > 0)) { mixLen++; entries++; } if (linker.Model._hasOpa = (opaLen > 0)) { opaLen++; entries++; } if (linker.Model._hasXlu = (xluLen > 0)) { xluLen++; entries++; } //Align data dataLen += (treeLen + mixLen + opaLen + xluLen).Align(4); break; } case MDLResourceType.Vertices: aInd = 0; aLen = 1; EvalAssets: List <ResourceNode> polyList = linker.Model._polyList; if (polyList == null) { break; } //What about merging? //Create asset lists IList aList; switch (aInd) { case 0: aList = linker._vertices = new List <VertexCodec>(polyList.Count); break; case 1: aList = linker._normals = new List <VertexCodec>(polyList.Count); break; case 2: aList = linker._colors = new List <ColorCodec>(polyList.Count); break; default: aList = linker._uvs = new List <VertexCodec>(polyList.Count); break; } aLen += aInd; temp = polyList.Count; for (int i = 0; i < temp; i++) { MDL0PolygonNode p = polyList[i] as MDL0PolygonNode; //object c; for (int x = aInd; x < aLen; x++) { if (p._manager._faceData[x] != null) { p._elementIndices[x] = (short)aList.Count; switch (aInd) { case 0: VertexCodec vert; aList.Add(vert = new VertexCodec(p._manager.RawPoints, true)); dataLen += vert._dataLen.Align(0x20) + 0x40; break; case 1: aList.Add(vert = new VertexCodec((Vector3 *)p._manager._faceData[x].Address, p._manager._pointCount, false)); dataLen += vert._dataLen.Align(0x20) + 0x20; break; case 2: ColorCodec col; aList.Add(col = new ColorCodec((RGBAPixel *)p._manager._faceData[x].Address, p._manager._pointCount)); dataLen += col._dataLen.Align(0x20) + 0x20; break; default: aList.Add(vert = new VertexCodec((Vector2 *)p._manager._faceData[x].Address, p._manager._pointCount)); dataLen += vert._dataLen.Align(0x20) + 0x40; break; } } else { p._elementIndices[x] = -1; } } } entries = aList.Count; break; case MDLResourceType.Normals: aInd = 1; aLen = 1; goto EvalAssets; case MDLResourceType.Colors: aInd = 2; aLen = 2; goto EvalAssets; case MDLResourceType.UVs: aInd = 4; aLen = 8; goto EvalAssets; case MDLResourceType.Bones: entryList = linker.BoneCache; break; case MDLResourceType.Materials: entryList = linker.Model._matList; break; case MDLResourceType.Polygons: entryList = linker.Model._polyList; break; case MDLResourceType.Shaders: if ((entryList = linker.Model._shadList) != null) { entries = linker.Model._shadList.Count; } break; case MDLResourceType.Textures: TextureRef[] tex = linker.Model._textures.GetTextures(); entries = tex.Length; foreach (TextureRef t in tex) { texCount++; texLen += t._texRefs.Count * 8 + 4; } break; case MDLResourceType.Decals: TextureRef[] dec = linker.Model._textures.GetDecals(); entries = dec.Length; foreach (TextureRef t in dec) { decCount++; texLen += t._decRefs.Count * 8 + 4; } break; } if (entryList != null) { int index = 0; foreach (MDL0EntryNode e in entryList) { e._entryIndex = index++; dataLen += e.CalculateSize(true); } if (entries == 0) { entries = index; } } if (entries > 0) { groupLen += entries * 0x10 + 0x18; } } linker._headerLen = headerLen; linker._tableLen = tableLen; linker._groupLen = groupLen; linker._texLen = texLen; linker._texCount = texCount; linker._decCount = decCount; linker._dataLen = dataLen; return(headerLen + tableLen + groupLen + texLen + dataLen); }
internal unsafe void Precalc(MDL0PolygonNode parent, IMatrixNode[] nodes) { //If already calculated, and no weights, skip? bool hasNodes = parent.Model._linker.NodeCache.Length > 0; if ((_precVertices != null) && hasNodes) { return; } Vector3[] verts, norms = null; Vector3 * vPtr = null, nPtr = null; RGBAPixel[][] colors = new RGBAPixel[2][]; Vector2[][] uvs = new Vector2[8][]; uint * ptrCache = stackalloc uint[10]; //Points verts = parent._vertexNode.Vertices; if (_precVertices == null) { _precVertices = new UnsafeBuffer(_elementCount * 12); } vPtr = (Vector3 *)_precVertices.Address; //Normals if (parent._normalNode != null) { norms = parent._normalNode.Normals; if (_precNormals == null) { _precNormals = new UnsafeBuffer(_elementCount * 12); } nPtr = (Vector3 *)_precNormals.Address; } else if (_precNormals != null) { _precNormals.Dispose(); _precNormals = null; } ////Colors //for (int i = 0; i < 1; i++) //{ // if (parent._colorSet[i] != null) // { // colors[i] = parent._colorSet[i].Colors; // if (_precColors == null) // _precColors = new UnsafeBuffer(_elementCount * 4); // ptrCache[i] = (uint)_precColors.Address; // } // else if (_precColors != null) // { // _precColors.Dispose(); // _precColors = null; // } //} //UVs for (int i = 0; i < 8; i++) { if (parent._uvSet[i] != null) { uvs[i] = parent._uvSet[i].Points; if (_precUVs[i] == null) { _precUVs[i] = new UnsafeBuffer(_elementCount * 8); } ptrCache[i + 2] = (uint)_precUVs[i].Address; } else if (_precUVs[i] != null) { _precUVs[i].Dispose(); _precUVs[i] = null; } } int count = _vertices.Count; for (int x = 0; x < count; x++) { Vertex3 vert = _vertices[x]; ////Vertices //if (hasNodes) // *vPtr++ = nodes[vert.Influence.NodeIndex].Matrix.Multiply(verts[vert.Position]); //else // *vPtr++ = verts[vert.Position]; ////Normals //if (nPtr != null) //{ // if (hasNodes) // *nPtr++ = nodes[vert.Influence.NodeIndex].Matrix.Multiply(norms[vert.Normal]); // else // *nPtr++ = norms[vert.Normal.Length]; //} ////Colors //for (int i = 0; i < 1; i++) //{ // RGBAPixel* cPtr = (RGBAPixel*)ptrCache[i]; // if (cPtr != null) // cPtr[x] = colors[i][vert.Color[i]]; //} ////UVs //for (int i = 0; i < 8; i++) //{ // Vector2* uPtr = (Vector2*)ptrCache[i + 2]; // if (uPtr != null) // uPtr[x] = uvs[i][vert.UV[i]]; //} } }
private void ImportObject(MDL0PolygonNode node) { MDL0PolygonNode newNode = node.Clone(); if (node._vertexNode != null) { _internalModel.VertexGroup.AddChild(node._vertexNode); (newNode._vertexNode = (MDL0VertexNode)_internalModel.VertexGroup.Children[_internalModel._vertList.Count - 1])._polygons.Add(newNode); } if (node.NormalNode != null) { _internalModel.NormalGroup.AddChild(node._normalNode); (newNode._normalNode = (MDL0NormalNode)_internalModel.NormalGroup.Children[_internalModel._normList.Count - 1])._polygons.Add(newNode); } for (int i = 0; i < 8; i++) { if (node.UVNodes[i] != null) { _internalModel.UVGroup.AddChild(node.UVNodes[i]); newNode._uvSet[i] = (MDL0UVNode)_internalModel.UVGroup.Children[_internalModel._uvList.Count - 1]; newNode._uvSet[i].Name = "#" + (_internalModel._uvList.Count - 1); newNode._uvSet[i]._polygons.Add(newNode); } } for (int i = 0; i < 2; i++) { if (node._colorSet[i] != null) { _internalModel.ColorGroup.AddChild(node._colorSet[i]); //(newNode._colorSet[i] = (MDL0ColorNode)_internalModel.ColorGroup.Children[_internalModel._colorList.Count - 1])._polygons.Add(newNode); } } _internalModel._matGroup.AddChild(node._material); newNode.MaterialNode = (MDL0MaterialNode)_internalModel.MaterialGroup.Children[_internalModel._matList.Count - 1]; _internalModel._shadGroup.AddChild(node._material._shader); newNode._material.ShaderNode = (MDL0ShaderNode)_internalModel.ShaderGroup.Children[_internalModel._shadList.Count - 1]; foreach (MDL0MaterialRefNode r in newNode._material.Children) { if (r._texture != null) { (r._texture = _internalModel.FindOrCreateTexture(r.TextureNode.Name))._references.Add(r); } if (r._palette != null) { (r._palette = _internalModel.FindOrCreatePalette(r.PaletteNode.Name))._references.Add(r); } } if (node.Weighted) { foreach (Vertex3 vert in node._manager._vertices) { if (vert._influence != null && vert._influence is Influence) { vert._influence = _internalModel._influences.AddOrCreateInf((Influence)vert._influence); } } } else if (node.SingleBindInf != null && node.SingleBindInf is Influence) { node.SingleBindInf = _internalModel._influences.AddOrCreateInf((Influence)node.SingleBindInf); } newNode.RecalcIndices(); newNode._bone = (MDL0BoneNode)_internalModel.BoneGroup.Children[0]; newNode._manager = node._manager; newNode.Name = "polygon" + (_internalModel._polyList.Count); newNode.SignalPropertyChange(); _internalModel._polyGroup.AddChild(newNode); newNode.Rebuild(true); }
public void GetPrimitives(MDL0Polygon *header, MDL0PolygonNode polygon) { AssetStorage assets = Model._assets; IMatrixNode[] influences = Model._linker.NodeCache; byte *[] pAssetList = new byte *[12]; int id; //Sync Data if ((id = header->_vertexId) >= 0) { pAssetList[0] = (byte *)assets.Assets[0][id].Address; } if ((id = header->_normalId) >= 0) { pAssetList[1] = (byte *)assets.Assets[1][id].Address; } for (int i = 0, x = 2; i < 2; i++, x++) { if ((id = ((bshort *)header->_colorIds)[i]) >= 0) { pAssetList[x] = (byte *)assets.Assets[2][id].Address; } } for (int i = 0, x = 4; i < 8; i++, x++) { if ((id = ((bshort *)header->_uids)[i]) >= 0) { pAssetList[x] = (byte *)assets.Assets[3][id].Address; } } //Set definition _elemDef = new ElementDefinition(); _elemDef.Weighted = polygon.VertexFormat.HasPosMatrix; _elemDef.PositionFmt = polygon.VertexFormat.PosFormat; _elemDef.Normals = (_elemDef.NormalFmt = polygon.VertexFormat.NormalFormat) != XFDataFormat.None; for (int i = 0; i < 2; i++) { _elemDef.Colors[i] = (_elemDef.ColorFmt[i] = polygon.VertexFormat.GetColorFormat(i)) != XFDataFormat.None; } for (int i = 0; i < 8; i++) { _elemDef.UVs[i] = (_elemDef.UVFmt[i] = polygon.VertexFormat.GetUVFormat(i)) != XFDataFormat.None; } for (int i = 0; i < 8; i++) { _elemDef.TexMatrices[i] = polygon.VertexFormat.GetHasTexMatrix(i); } List <FacePoint> facePoints = new List <FacePoint>(); //Create script using definition for decoding and rendering _script = new PrimitiveScript(_elemDef); //Create remap table for vertex weights RemapTable = new UnsafeBuffer(header->_numVertices * 4); RemapSize = 0; //Extract primitives using script byte *pData = (byte *)header->PrimitiveData; int count; GLPrimitiveType type; int ind = 0; _facePoints = new UnsafeBuffer((_facePointCount = header->_numVertices) * 86); FacePoint *points = (FacePoint *)_facePoints.Address; Top: switch ((WiiPrimitiveType)(*pData++)) { //Fill weight cache case WiiPrimitiveType.PosMtx: //Get node ID ushort node = *(bushort *)pData; //Get cache index int index = (*(bushort *)(pData + 2) & 0xFFF) / 12; //Assign node ID to cache, using index fixed(ushort *n = _script.Nodes) n[index] = node; pData += 4; goto Top; case WiiPrimitiveType.NorMtx: //Same as PosMtx case WiiPrimitiveType.TexMtx: case WiiPrimitiveType.LightMtx: pData += 4; //Skip goto Top; case WiiPrimitiveType.Quads: type = GLPrimitiveType.Quads; break; case WiiPrimitiveType.Triangles: type = GLPrimitiveType.Triangles; break; case WiiPrimitiveType.TriangleFan: type = GLPrimitiveType.TriangleFan; break; case WiiPrimitiveType.TriangleStrip: type = GLPrimitiveType.TriangleStrip; break; case WiiPrimitiveType.Lines: type = GLPrimitiveType.Lines; break; case WiiPrimitiveType.LineStrip: type = GLPrimitiveType.LineStrip; break; case WiiPrimitiveType.Points: type = GLPrimitiveType.Points; break; default: goto Next; //No more primitives. } count = *(bushort *)pData; pData += 2; Primitive2 prim = new Primitive2() { _type = type, _elements = count }; prim._indices = new int[count]; //Extract facepoints fixed(byte **pAssets = pAssetList) for (int i = 0; i < count; i++) { points[ind] = ExtractFacepoint(ref pData, pAssets); prim._indices[i] = (ushort)ind++; } _primitives.Add(prim); goto Top; //Move on to next primitive Next : _vertices = Finish((Vector3 *)pAssetList[0], influences); }
private static unsafe void WritePrimitive(MDL0PolygonNode poly, NewPrimitive prim, XmlWriter writer) { PrimitiveManager manager = poly._manager; int count; int elements = 0, stride = 0; int set; bool first; ushort *pData = (ushort *)prim._indices.Address; ushort *pVert = (ushort *)poly._manager._indices.Address; switch (prim._type) { case GLPrimitiveType.Triangles: writer.WriteStartElement("triangles"); stride = 3; break; case GLPrimitiveType.Lines: writer.WriteStartElement("lines"); stride = 2; break; case GLPrimitiveType.Points: writer.WriteStartElement("points"); stride = 1; break; } count = prim._elementCount / stride; if (poly._material != null) { writer.WriteAttributeString("material", poly._material.Name); } writer.WriteAttributeString("count", count.ToString()); for (int i = 0; i < 12; i++) { if (manager._faceData[i] == null) { continue; } writer.WriteStartElement("input"); switch (i) { case 0: writer.WriteAttributeString("semantic", "VERTEX"); writer.WriteAttributeString("source", "#" + poly._name + "_Vertices"); break; case 1: writer.WriteAttributeString("semantic", "NORMAL"); writer.WriteAttributeString("source", "#" + poly._name + "_Normals"); break; case 2: case 3: set = i - 2; writer.WriteAttributeString("semantic", "COLOR"); writer.WriteAttributeString("source", "#" + poly._name + "_Colors" + set.ToString()); writer.WriteAttributeString("set", set.ToString()); break; default: set = i - 4; writer.WriteAttributeString("semantic", "TEXCOORD"); writer.WriteAttributeString("source", "#" + poly._name + "_UVs" + set.ToString()); writer.WriteAttributeString("set", set.ToString()); break; } writer.WriteAttributeString("offset", elements.ToString()); writer.WriteEndElement(); //input elements++; } for (int i = 0; i < count; i++) { writer.WriteStartElement("p"); first = true; for (int x = 0; x < stride; x++) { int index = *pData++; for (int y = 0; y < elements; y++) { if (first) { first = false; } else { writer.WriteString(" "); } if (y == 0) { writer.WriteString(pVert[index].ToString()); } else { writer.WriteString(index.ToString()); } } } writer.WriteEndElement(); //p } writer.WriteEndElement(); //primitive }
private static void WritePolygon(StreamWriter writer, MDL0PolygonNode poly) { if (poly._manager._vertices != null) { int count = poly._manager._vertices.Count; Vector3[] Vertices = new Vector3[count]; DialogResult result = MessageBox.Show("Do you want to export the weighted positions of the vertices?", "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) { //Weight vertices foreach (Influence inf in (poly.Model)._influences._influences) { inf.CalcMatrix(); } poly._manager.Weight(); //Set weighted positions for (int i = 0; i < count; i++) { if (poly._manager._vertices[i].WeightedPosition.ToString() != "(0,0,0)") { Vertices[i] = poly._manager._vertices[i].WeightedPosition; } else { Vertices[i] = poly._manager._vertices[i].Position; } } } else if (result == DialogResult.No) { //Set raw positions for (int i = 0; i < count; i++) { Vertices[i] = poly._manager._vertices[i].Position; } } if (result != DialogResult.Cancel) //Export { WriteVertexGroup(writer, Vertices); } } if (poly._manager._faceData[1] != null) { WriteNormalGroup(writer, poly._manager, true); } for (int i = 0; i < 1; i++) //Obj only supports 1 uv coord set... { if (poly._manager._faceData[i + 4] != null) { WriteUVGroup(writer, poly._manager._faceData[i + 4]); } } writer.WriteLine(); writer.WriteLine(String.Format("g {0}", poly.Name)); //if (poly._material != null) // WriteMaterial(writer, poly._material); //if (poly.Primitives != null) // foreach (Primitive p in poly.Primitives) // { // switch (p._type) // { // case GLPrimitiveType.TriangleFan: // WriteTriFan(writer, p); // break; // case GLPrimitiveType.TriangleStrip: // WriteTriStrip(writer, p); // break; // case GLPrimitiveType.Triangles: // WriteTriList(writer, p); // break; // case GLPrimitiveType.Quads: // WriteQuadList(writer, p); // break; // } // } if (poly._manager != null) { if (poly._manager._triangles != null) { WriteTriList(writer, poly._manager); } //if (poly._manager._lines != null) //{ //} //if (poly._manager._points != null) //{ //} } }