private void importFromDAEToolStripMenuItem_Click(object sender, EventArgs e) { if (!(treeView1.SelectedNode is ModelContainer)) { return; } using (OpenFileDialog ofd = new OpenFileDialog()) { if (ofd.ShowDialog() == DialogResult.OK) { DAEImportSettings m = new DAEImportSettings(); m.ShowDialog(); if (m.exitStatus == DAEImportSettings.Opened) { ModelContainer con = (ModelContainer)treeView1.SelectedNode; con.VBN = m.getVBN(); Collada.DAEtoNUD(ofd.FileName, con, m.checkBox5.Checked); // apply settings m.Apply(con.NUD); con.NUD.MergePoly(); } } } }
public void Import(object o, EventArgs a) { using (OpenFileDialog sfd = new OpenFileDialog()) { sfd.ShowDialog(); foreach (string f in sfd.FileNames) { if (f.ToLower().EndsWith(".dae")) { DAEImportSettings daeImport = new DAEImportSettings(); daeImport.ShowDialog(); if (daeImport.exitStatus == DAEImportSettings.ExitStatus.Opened) { ModelContainer con = new ModelContainer(); // load vbn con.VBN = skeleton; Collada.DaetoNud(f, con, daeImport.importTexCB.Checked); if (con.NUD != null) { // apply settings daeImport.Apply(con.NUD); CreateFromNUD(con.NUD); } } } } } }
public void Import(object o, EventArgs a) { using (OpenFileDialog sfd = new OpenFileDialog()) { sfd.ShowDialog(); foreach (string f in sfd.FileNames) { if (f.ToLower().EndsWith(".dae")) { DAEImportSettings m = new DAEImportSettings(); m.ShowDialog(); if (m.exitStatus == DAEImportSettings.Opened) { ModelContainer con = new ModelContainer(); // load vbn con.vbn = skeleton; Collada.DAEtoNUD(f, con, m.checkBox5.Checked); // apply settings m.Apply(con.nud); con.nud.MergePoly(); CreateFromNUD(con.nud); } } } } }
public static void WriteMesh(string filename, RectList rects) { List <ulong> palette = FindRgbaPalette(rects); _nodeid = 1; var scene = new ColladaScene { Id = _nodeid++ }; var collada = new Collada(); collada.Scenes.Add(scene); foreach (ulong rgba in palette) { var effect = new ColladaEffect(); Converter.Ulong2Rgba(rgba, out effect.R, out effect.G, out effect.B, out effect.A); var material = new ColladaMaterial { Id = _nodeid++ }; effect.Id = _nodeid++; material.Url = effect.Id; effect.Rgba = rgba; collada.Materials.Add(material); collada.Effects.Add(effect); } foreach (Rect rect in rects) { var geom = new ColladaGeometry { Id = _nodeid++, PositionId = _nodeid++, NormalId = _nodeid++, PositionId2 = _nodeid++, NormalId2 = _nodeid++, VertexId = _nodeid++ }; int material = collada.FindMaterial(rect.Properties.Rgba); geom.Materialid = material; geom.X1 = rect.Pt1[0]; geom.Y1 = rect.Pt1[1]; geom.Z1 = rect.Pt1[2]; geom.X2 = rect.Pt2[0]; geom.Y2 = rect.Pt2[1]; geom.Z2 = rect.Pt2[2]; collada.Geometries.Add(geom); scene.Geometry.Add(geom.Id); } collada.WriteMesh(filename); }
public override unsafe void Export(string outPath) { if (outPath.EndsWith(".dae")) { //Model model = GetModel(); Collada.Serialize(this, outPath); } else { base.Export(outPath); } }
private void exportAsDAEToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog save = new SaveFileDialog(); save.Filter = "Supported Filetypes (DAE)|*.dae;|All files(*.*)|*.*"; DialogResult result = save.ShowDialog(); if (result == DialogResult.OK && treeView1.SelectedNode is ModelContainer) { Collada.Save(save.FileName, (ModelContainer)treeView1.SelectedNode); } }
/// <summary> /// Unload contents /// </summary> public override void UnloadContent() { if (Collada != null) { Collada.Dispose(); } Collada = null; if (MD5 != null) { MD5.Dispose(); } MD5 = null; }
public override unsafe void Export(string outPath) { if (outPath.EndsWith(".dae", StringComparison.OrdinalIgnoreCase)) { Collada.Serialize(new CHR0Node[] { this }, 60.0f, false, outPath); } else if (outPath.EndsWith(".anim", StringComparison.OrdinalIgnoreCase)) { AnimFormat.Serialize(this, false, outPath); } else { base.Export(outPath); } }
public byte[] ExportCollada() { Collada colladaDoc = new Collada(_geometry.ToArray(), _index.ToArray(), Id); System.Type[] extraTypes = new System.Type[] { typeof(Collada.Asset), typeof(Collada.Asset.Contributor), typeof(Collada.Asset.Unit) }; MemoryStream memoryStream = new MemoryStream(); XmlSerializer xmlSerializerHeader = new XmlSerializer(colladaDoc.GetType(), extraTypes); xmlSerializerHeader.Serialize(memoryStream, colladaDoc); return(memoryStream.ToArray()); }
public ColladaScene(string pointer) { colladaAnimationDataGenerator = new AnimationDataGenerator(); prepareFile(pointer); XmlTextReader reader = new XmlTextReader(pointer); stepSize = 1.0f / 10; while (reader.Read()) { if (reader.Name == "COLLADA") collada = new Collada(ref reader, this); } reader.Close(); }
public static MDL0Node FromFile(string path) { string ext = Path.GetExtension(path); if (path.EndsWith(".mdl", StringComparison.OrdinalIgnoreCase)) { return(NodeFactory.FromFile(null, path) as MDL0Node); } if (path.EndsWith(".dae", StringComparison.OrdinalIgnoreCase)) { return(Collada.ImportModel(path)); } //else if (string.Equals(ext, "fbx", StringComparison.OrdinalIgnoreCase)) //{ //} //else if (string.Equals(ext, "blender", StringComparison.OrdinalIgnoreCase)) //{ //} throw new NotSupportedException("The file extension specified is not of a supported model type."); }
public static async Task <RenderVertex[]> GetVerticesAsync(string filename) { var result = await Collada.ImportAsync(filename, new ColladaImportOptions(), new Progress <float>(), CancellationToken.None); var vertices = new List <RenderVertex>(); foreach (var scene in result.Scenes) { foreach (var subMesh in scene.Model.Children) { for (int i = 0; i < subMesh.Primitives.Triangles.Count; i++) { var face = subMesh.Primitives.GetFace(i); vertices.Add(GetVertex(face.Vertex0)); vertices.Add(GetVertex(face.Vertex1)); vertices.Add(GetVertex(face.Vertex2)); } } } return(vertices.ToArray()); }
private async void btnImport_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(textBox1.Text)) { return; } _cancel = new CancellationTokenSource(); btnCancel.Enabled = true; Progress <float> progress = new Progress <float>(); progress.ProgressChanged += Progress_ProgressChanged; tabControl1.SelectTab(1); var scenes = await Collada.ImportAsync(textBox1.Text, _options, progress, _cancel.Token); btnCancel.Enabled = false; _cancel = null; PrintOutput(scenes); progress.ProgressChanged -= Progress_ProgressChanged; progressBar1.Value = progressBar1.Maximum; }
public static int CalcSize(Collada form, ModelLinker linker) { MDL0Node model = linker.Model; model._needsNrmMtxArray = model._needsTexMtxArray = false; model._numFacepoints = model._numTriangles = 0; 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) { MDL0BoneNode bone = w.Bone as MDL0BoneNode; if (bone != null && w.Weight != 0 && bone._nodeIndex < linker.NodeCache.Length && bone._nodeIndex >= 0 && linker.NodeCache[bone._nodeIndex] is MDL0BoneNode) { mixLen += 6; } } } foreach (MDL0BoneNode b in linker.BoneCache) { if (b._weightCount > 0) { mixLen += 5; } } //DrawOpa and DrawXlu //Get assigned materials and categorize if (model._objList != null) { for (int i = 0; i < model._objList.Count; i++) { //Entries are ordered by material, not by polygon. //Using the material's attached polygon list is untrustable if the definitions were corrupt on parse. MDL0ObjectNode poly = model._objList[i] as MDL0ObjectNode; model._numTriangles += poly._numFaces; model._numFacepoints += poly._numFacepoints; foreach (DrawCall c in poly._drawCalls) { if (c.DrawPass == DrawCall.DrawPassType.Opaque) { 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._objList; if (polyList == null) { break; } string str = ""; bool direct = linker._forceDirectAssets[aInd]; //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++) { MDL0ObjectNode obj = polyList[i] as MDL0ObjectNode; for (int x = aInd; x < aLen; x++) { if (obj._manager._faceData[x] != null) { //Remap color nodes if ((x == 2 || x == 3)) { if (Collada._importOptions._rmpClrs) { obj._elementIndices[x] = -1; foreach (MDL0ObjectNode thatObj in polyList.OrderBy(c => - ((MDL0ObjectNode)c)._manager.GetColors(x - 2, false).Length)) { //Only compare up to the current object if (thatObj == obj) { break; } var thatArr = thatObj._manager.GetColors(x - 2, false); var thisArr = obj._manager.GetColors(x - 2, false); bool equals = true; if (thisArr.Length == thatArr.Length) { for (int n = 0; n < thisArr.Length; n++) { if (thisArr[n] != thatArr[n]) { equals = false; break; } } } else { foreach (RGBAPixel px in thisArr) { if (Array.IndexOf(thatArr, px) < 0) { equals = false; break; } } } if (equals) { //Found a match obj._elementIndices[x] = thatObj._elementIndices[x]; obj._manager._newClrObj[x - 2] = thatObj.Index; break; } } if (obj._elementIndices[x] != -1) { continue; } } else { obj._manager._newClrObj[x - 2] = i; } } obj._elementIndices[x] = (short)aList.Count; if (form != null) { form.Say("Encoding " + str + (x - aInd) + " for Object " + i + ": " + obj.Name); } VertexCodec vert; switch (aInd) { case 0: vert = new VertexCodec(obj._manager.GetVertices(false), false, Collada._importOptions._fltVerts); aList.Add(vert); if (!direct) { assetLen += vert._dataLen.Align(0x20) + 0x40; } break; case 1: vert = new VertexCodec(obj._manager.GetNormals(false), false, Collada._importOptions._fltNrms); aList.Add(vert); if (!direct) { assetLen += vert._dataLen.Align(0x20) + 0x20; } break; case 2: ColorCodec col = new ColorCodec(obj._manager.GetColors(x - 2, false)); aList.Add(col); if (!direct) { assetLen += col._dataLen.Align(0x20) + 0x20; } break; default: vert = new VertexCodec(obj._manager.GetUVs(x - 4, false), Collada._importOptions._fltUVs); aList.Add(vert); if (!direct) { assetLen += vert._dataLen.Align(0x20) + 0x40; } break; } } else { obj._elementIndices[x] = -1; } } } if (!direct) { 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 { if (Collada._importOptions._useOneNode) { HashSet <RGBAPixel> pixels = new HashSet <RGBAPixel>(); if (model._objList != null) { foreach (MDL0ObjectNode obj in model._objList) { for (int i = 0; i < 2; i++) { var arr = obj._manager.GetColors(i, false); if (arr.Length > 0) { obj._elementIndices[i + 2] = 0; foreach (RGBAPixel p in arr) { pixels.Add(p); } } else { obj._elementIndices[i + 2] = -1; } } } } var le = pixels.ToList(); le.Sort(); if (le.Count == 0) { break; } Collada._importOptions._singleColorNodeEntries = le.ToArray(); ColorCodec col = new ColorCodec(Collada._importOptions._singleColorNodeEntries); linker._colors = new List <ColorCodec>() { col }; assetLen += col._dataLen.Align(0x20) + 0x20; entries = 1; } 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._objList != null) { entryList = model._objList; foreach (MDL0ObjectNode n in model._objList) { if (n.NormalNode != null || n._manager._faceData[1] != null) { model._needsNrmMtxArray = true; } if (n.HasTexMtx) { model._needsTexMtxArray = true; } } } break; case MDLResourceType.Shaders: if (model._matList != null && (entryList = model.GetUsedShaders()) != null) { entries = model._matList.Count; } break; case MDLResourceType.Textures: if (model._texList != null) { List <MDL0TextureNode> texNodes = new List <MDL0TextureNode>(); foreach (MDL0TextureNode tex in model._texList) { texNodes.Add(tex); texLen += (tex._references.Count * 8) + 4; } entries = (linker._texList = texNodes).Count; } break; case MDLResourceType.Palettes: if (model._pltList != null) { List <MDL0TextureNode> pltNodes = new List <MDL0TextureNode>(); foreach (MDL0TextureNode plt in model._pltList) { pltNodes.Add(plt); texLen += (plt._references.Count * 8) + 4; } entries = (linker._pltList = pltNodes).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); } if (index != 0) { e._mdlOffset = (prev = ((MDL0MaterialNode)model._matList[index - 1]))._mdlOffset + prev._calcSize; } else if ((temp = (e._mdlOffset = headerLen + tableLen + groupLen + texLen + defLen + boneLen).Align(0x10)) != e._mdlOffset) { e._dataAlign = temp - e._mdlOffset; } e._entryIndex = index++; dataLen += e.CalculateSize(true); } } if (model._isImport && model._objList != null) { foreach (MDL0ObjectNode obj1 in model._objList) { if (obj1 == null || obj1._drawCalls == null || obj1._drawCalls.Count == 0) { continue; } MDL0MaterialNode p = obj1._drawCalls[0].MaterialNode; if (p == null) { continue; } //Set materials to use register color if option set if (!Collada._importOptions._useReg && linker._colors != null && linker._colors.Count > 0) { p.C1AlphaMaterialSource = GXColorSrc.Vertex; p.C1ColorMaterialSource = GXColorSrc.Vertex; } else { p.C1MaterialColor = Collada._importOptions._dfltClr; p.C1ColorMaterialSource = GXColorSrc.Register; p.C1AlphaMaterialSource = GXColorSrc.Register; } } } 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) + (linker.Version > 9 ? model._userEntries.GetSize() : 0)); }
internal static unsafe void Build(Collada form, ModelLinker linker, MDL0Header *header, int length, bool force) { byte *groupAddr = (byte *)header + linker._headerLen + linker._tableLen; byte *dataAddr = groupAddr + linker._groupLen + linker._texLen; //Definitions start here byte *assetAddr = dataAddr + linker._defLen + linker._boneLen + linker._dataLen; linker.Header = header; if (form != null) { form.Say("Writing header..."); } //Create new model header *header = new MDL0Header(length, linker.Version); if (form != null) { form.Say("Writing node table..."); } //Write node table, assign node ids WriteNodeTable(linker); if (form != null) { form.Say("Writing definitions..."); } //Write def table WriteDefs(linker, ref groupAddr, ref dataAddr); //Set format list for each polygon's UVAT groups SetFormatLists(linker); //Write assets first, but only if the model is an import if (linker.Model._isImport) { WriteAssets(form, linker, ref assetAddr); } //Write groups linker.Write(form, ref groupAddr, ref dataAddr, force); //Write user entries if (linker.Model._userEntries.Count > 0 && linker.Version > 9) { header->UserDataOffset = (int)dataAddr - (int)header; linker.Model._userEntries.Write(header->UserData); } else { header->UserDataOffset = 0; } //Write textures WriteTextures(linker, ref groupAddr); //Set box min and box max if (linker.Model._isImport) { SetBox(linker); } //Store group offsets linker.Finish(); //Set new properties *header->Properties = new MDL0Props(linker.Version, linker.Model._numFacepoints, linker.Model._numTriangles, linker.Model._numNodes, linker.Model._scalingRule, linker.Model._texMtxMode, linker.Model._needsNrmMtxArray, linker.Model._needsTexMtxArray, linker.Model._enableExtents, linker.Model._envMtxMode, linker.Model._extents.Min, linker.Model._extents.Max); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); Version version = new Version(GL.GetString(StringName.Version).Substring(0, 3)); Version target = new Version(3, 0); if (version < target) { throw new NotSupportedException(String.Format("OpenGL {0} is required (you only have {1}).", target, version)); } Vector <float> camera_pos = new Vector <float>(0, 0, -20); Vector <float> camera_forward = new Vector <float>(0, 0, 1); Vector <float> camera_up = new Vector <float>(0, 1, 0); camera = new Camera(camera_pos, camera_forward, camera_up); string xml_file_contents; var assembly = Assembly.GetExecutingAssembly(); var modelFile = "GraphicsWindow.Resources.model.dae"; using (Stream stream = assembly.GetManifestResourceStream(modelFile)) using (StreamReader reader = new StreamReader(stream)) { xml_file_contents = reader.ReadToEnd(); } Model model = Collada.Parse(xml_file_contents); #region Debugging //Collada_OLD.AnimatedModelData data = Collada_OLD.Collada.LoadModel(xml_file_contents, 3); //Collada_OLD.AnimationData animdata = Collada_OLD.Collada.LoadAnimation(xml_file_contents); //if (!model._positions.ValuesAreEqual(data.mesh.vertices)) // throw new Exception("positions"); //if (!model._normals.ValuesAreEqual(data.mesh.normals)) // throw new Exception("normals"); //if (!model._indices.ValuesAreEqual(data.mesh.indices)) // throw new Exception("indices"); //if (!model._textureCoordinates.ValuesAreEqual(data.mesh.textureCoords)) // throw new Exception("textureCoordinates"); //if (!Collada.EFFECTORJOINTCOUNTS.ValuesAreEqual(Collada_OLD.EFFECTORJOINTCOUNTS)) // throw new Exception("EFFECTORJOINTCOUNTS"); //if (!Collada.WEIGHTS.ValuesAreEqual(Collada_OLD.WEIGHTS)) // throw new Exception("WEIGHTS"); //if (!Collada.JOINTIDSDATA.ValuesAreEqual(Collada_OLD.JOINTIDSDATA)) // throw new Exception("JOINTIDSDATA"); //if (!Collada.JOINTWEIGHTSDATA.ValuesAreEqual(Collada_OLD.JOINTWEIGHTSDATA)) // throw new Exception("JOINTWEIGHTSDATA"); //if (!model._jointWeights.ValuesAreEqual(data.mesh.vertexWeights)) // throw new Exception("jointWeights"); //if (!model._jointIds.ValuesAreEqual(data.mesh.jointIds)) // throw new Exception("jointIds"); ////model._jointIds = data.mesh.jointIds; ////model._jointWeights = data.mesh.vertexWeights; #endregion var textureFile = "GraphicsWindow.Resources.diffuse.png"; Bitmap texture = new Bitmap(assembly.GetManifestResourceStream(textureFile)); model._texture = texture; loadedModel = Theta.Graphics.OpenGL.Load.Model(model); loadedModel.ActivateAnimation("base animation"); animatedModelShader = new Render.AnimatedModelShader(); lightDirection = new Vector <float>(0.2f, -0.3f, -0.8f); }
public void Write(Collada form, ref byte *pGroup, ref byte *pData, bool force) { MDL0GroupNode group; ResourceGroup *pGrp; ResourceEntry *pEntry; int len; //Write data in the order it appears foreach (MDLResourceType resType in OrderBank) { if (((group = Groups[(int)resType]) == null) || SpecialRebuildData((int)resType)) { continue; } if (resType == MDLResourceType.Bones) { if (form != null) { form.Say("Writing Bones"); } MDL0Bone *pBone = (MDL0Bone *)pData; foreach (MDL0BoneNode e in BoneCache) { len = e._calcSize; e.Rebuild(pData, len, true); pData += len; } //Loop through after all bones are written //and set header offsets to related bones foreach (MDL0BoneNode e in BoneCache) { e.CalculateOffsets(); } } else if (resType == MDLResourceType.Shaders) { MDL0GroupNode mats = Groups[(int)MDLResourceType.Materials]; MDL0Material *mHeader; if (form != null) { form.Say("Writing Shaders"); } //Write data without headers foreach (ResourceNode e in group.Children) { if (((MDL0ShaderNode)e)._materials.Count > 0) { len = e._calcSize; e.Rebuild(pData, len, force); pData += len; } } //Write one header for each material, using same order. if (mats != null) { foreach (MDL0MaterialNode mat in mats.Children) { mHeader = mat.Header; if (mat._shader != null) { len = (int)mat._shader.Header; mHeader->_shaderOffset = len - (int)mHeader; } else { mHeader->_shaderOffset = 0; } } } } else if (resType == MDLResourceType.Objects || resType == MDLResourceType.Materials) { foreach (ResourceNode r in group.Children) { if (form != null) { form.Say("Writing " + resType.ToString() + " - " + r.Name); } len = r._calcSize; r.Rebuild(pData, len, true); //Forced to fix object node ids and align materials pData += len; } } else { bool rebuild = true; if (Model._isImport) { if (group._name == "Vertices" || group._name == "Normals" || group._name == "UVs" || group._name == "Colors") { rebuild = false; //The data has already been written! } } if (rebuild) { foreach (ResourceNode e in group.Children) { //Console.WriteLine("Rebuilding the " + group.Name); if (form != null) { form.Say("Writing the " + resType.ToString() + " - " + e.Name); } len = e._calcSize; e.Rebuild(pData, len, true); //Forced just in case we need to convert to float. pData += len; } } } } //Write relocation offsets in the order of the header fixed(ResourceGroup **pOut = &Defs) foreach (MDLResourceType resType in IndexBank[Version]) { if (((group = Groups[(int)resType]) == null) || SpecialRebuildData((int)resType)) { continue; } pOut[(int)resType] = pGrp = (ResourceGroup *)pGroup; pEntry = &pGrp->_first + 1; if (resType == MDLResourceType.Bones) { *pGrp = new ResourceGroup(BoneCache.Length); foreach (ResourceNode e in BoneCache) { (pEntry++)->_dataOffset = (int)((byte *)(e.WorkingUncompressed.Address) - pGroup); } } else if (resType == MDLResourceType.Shaders) { MDL0GroupNode mats = Groups[(int)MDLResourceType.Materials]; if (mats != null) { //Create a material group with the amount of entries *pGrp = new ResourceGroup(mats.Children.Count); foreach (MDL0MaterialNode mat in mats.Children) { (pEntry++)->_dataOffset = (int)mat._shader.Header - (int)pGrp; } } } else { *pGrp = new ResourceGroup(group.Children.Count); foreach (ResourceNode e in group.Children) { (pEntry++)->_dataOffset = (int)((byte *)(e.WorkingUncompressed.Address) - pGroup); } } pGroup += pGrp->_totalSize; } }
public void GenerateBinormalTangentBuffers(int positionIndex, int uvIndex, bool addBinormals, bool addTangents) { IDataBuffer[] pBuffs = GetAllBuffersOfType(EBufferType.Position); if (pBuffs.Length == 0) { Collada.WriteLine("No position buffers found."); return; } if (!pBuffs.IndexInRange(positionIndex)) { Collada.WriteLine("Position index out of range of available position buffers."); return; } //IDataBuffer[] nBuffs = GetAllBuffersOfType(EBufferType.Normal); //if (nBuffs.Length == 0) //{ // Console.WriteLine("No normal buffers found."); // return; //} //if (!nBuffs.IndexInRange(normalIndex)) //{ // Console.WriteLine("Normal index out of range of available normal buffers."); // return; //} IDataBuffer[] tBuffs = GetAllBuffersOfType(EBufferType.TexCoord); if (tBuffs.Length == 0) { Collada.WriteLine("No texcoord buffers found."); return; } if (!tBuffs.IndexInRange(uvIndex)) { Collada.WriteLine("UV index out of range of available texcoord buffers."); return; } Vec3 pos1, pos2, pos3; //Vec3 n0, n1, n2; Vec2 uv1, uv2, uv3; IDataBuffer pBuff = pBuffs[positionIndex]; //VertexBuffer nBuff = pBuffs[normalIndex]; IDataBuffer tBuff = tBuffs[uvIndex]; int pointCount = _triangles.Count * 3; List <Vec3> binormals = new List <Vec3>(pointCount); List <Vec3> tangents = new List <Vec3>(pointCount); for (int i = 0; i < _triangles.Count; ++i) { IndexTriangle t = _triangles[i]; FacePoint fp0 = _facePoints[t.Point0]; FacePoint fp1 = _facePoints[t.Point1]; FacePoint fp2 = _facePoints[t.Point2]; pos1 = (Vec3)pBuff[fp0.BufferIndices[pBuff.Index]]; pos2 = (Vec3)pBuff[fp1.BufferIndices[pBuff.Index]]; pos3 = (Vec3)pBuff[fp2.BufferIndices[pBuff.Index]]; uv1 = (Vec2)tBuff[fp0.BufferIndices[tBuff.Index]]; uv2 = (Vec2)tBuff[fp1.BufferIndices[tBuff.Index]]; uv3 = (Vec2)tBuff[fp2.BufferIndices[tBuff.Index]]; Vec3 deltaPos1 = pos2 - pos1; Vec3 deltaPos2 = pos3 - pos1; Vec2 deltaUV1 = uv2 - uv1; Vec2 deltaUV2 = uv3 - uv1; Vec3 tangent; Vec3 binormal; float m = deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X; if (m == 0.0f) { tangent = Vec3.UnitY; binormal = Vec3.UnitY; } else { float r = 1.0f / m; tangent = (deltaPos1 * deltaUV2.Y - deltaPos2 * deltaUV1.Y) * r; binormal = (deltaPos2 * deltaUV1.X - deltaPos1 * deltaUV2.X) * r; } binormals.Add(binormal); binormals.Add(binormal); binormals.Add(binormal); tangents.Add(tangent); tangents.Add(tangent); tangents.Add(tangent); } AddBuffer(binormals, EBufferType.Binormal); AddBuffer(tangents, EBufferType.Tangent); _bufferInfo.HasBinormals = true; _bufferInfo.HasTangents = true; }
}; // Default viewport #endregion #region ToolStripMenu private void openNUDToolStripMenuItem_Click(object sender, EventArgs e) { PARAMEditor currentParam = null; ACMDEditor currentACMD = null; SwagEditor currentSwagEditor = null; foreach (PARAMEditor p in paramEditors) { if (p.ContainsFocus) { currentParam = p; } } foreach (ACMDEditor a in ACMDEditors) { if (a.ContainsFocus) { currentACMD = a; } } foreach (SwagEditor s in SwagEditors) { if (s.ContainsFocus) { currentSwagEditor = s; } } if (currentParam != null) { currentParam.saveAs(); } else if (currentACMD != null) { currentACMD.save(); } else if (currentSwagEditor != null) { currentSwagEditor.save(); } else { string filename = ""; SaveFileDialog save = new SaveFileDialog(); save.Filter = "Supported Filetypes (VBN,LVD)|*.vbn;*.lvd;*.dae|Smash 4 Boneset|*.vbn|All files(*.*)|*.*"; DialogResult result = save.ShowDialog(); if (result == DialogResult.OK) { filename = save.FileName; if (filename.EndsWith(".vbn")) { Runtime.TargetVBN.Endian = Endianness.Big; if (!checkBox1.Checked) { Runtime.TargetVBN.Endian = Endianness.Little; } Runtime.TargetVBN.Save(filename); } if (filename.EndsWith(".lvd") && Runtime.TargetLVD != null) { File.WriteAllBytes(filename, Runtime.TargetLVD.Rebuild()); } else if (filename.EndsWith(".lvd")) { DAT d = null; foreach (ModelContainer c in Runtime.ModelContainers) { if (c.dat_melee != null) { d = c.dat_melee; } } if (d != null) { DialogResult r = MessageBox.Show("Would you like to save in safe mode?\n(This is not suggested, only use when needed)", "DAT -> LVD safe mode", MessageBoxButtons.YesNo); if (r == DialogResult.Yes) { File.WriteAllBytes(filename, d.toLVD(true).Rebuild()); } else if (r == DialogResult.No) { File.WriteAllBytes(filename, d.toLVD(false).Rebuild()); } } } if (filename.EndsWith(".dae")) { if (Runtime.ModelContainers.Count > 0) { Collada.Save(filename, Runtime.ModelContainers[0]); } } //OMO.createOMO (anim, vbn, "C:\\Users\\ploaj_000\\Desktop\\WebGL\\test_outut.omo", -1, -1); } } }
//Write assets will only be used for model imports. private static void WriteAssets(Collada form, ModelLinker linker, ref byte *pData) { int index; MDL0Node model = linker.Model; if (linker._vertices != null && linker._vertices.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Vertices)); model._vertGroup._parent = model; index = 0; foreach (VertexCodec c in linker._vertices) { MDL0VertexNode node = new MDL0VertexNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Vertices - " + node.Name); } MDL0VertexData *header = (MDL0VertexData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x40; header->_dataOffset = 0x40; header->_index = index++; header->_isXYZ = c._hasZ ? 1 : 0; header->_type = (int)c._type; header->_divisor = (byte)c._scale; header->_entryStride = (byte)c._dstStride; header->_numVertices = (ushort)c._dstCount; header->_eMin = c._min; header->_eMax = c._max; header->_pad1 = header->_pad2 = 0; c.Write(pData + 0x40); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._vertGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._normals != null && linker._normals.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Normals)); model._normGroup._parent = model; index = 0; foreach (VertexCodec c in linker._normals) { MDL0NormalNode node = new MDL0NormalNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Normals - " + node.Name); } MDL0NormalData *header = (MDL0NormalData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x20; header->_dataOffset = 0x20; header->_index = index++; header->_isNBT = 0; header->_type = (int)c._type; header->_divisor = (byte)c._scale; header->_entryStride = (byte)c._dstStride; header->_numVertices = (ushort)c._dstCount; c.Write(pData + 0x20); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._normGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._colors != null && linker._colors.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Colors)); model._colorGroup._parent = model; index = 0; foreach (ColorCodec c in linker._colors) { MDL0ColorNode node = new MDL0ColorNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Colors - " + node.Name); } MDL0ColorData *header = (MDL0ColorData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x20; header->_dataOffset = 0x20; header->_index = index++; header->_isRGBA = c._hasAlpha ? 1 : 0; header->_format = (int)c._outType; header->_entryStride = (byte)c._dstStride; header->_pad = 0; header->_numEntries = (ushort)c._dstCount; c.Write(pData + 0x20); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._colorGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._uvs != null && linker._uvs.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.UVs)); model._uvGroup._parent = model; index = 0; foreach (VertexCodec c in linker._uvs) { MDL0UVNode node = new MDL0UVNode() { _name = "#" + index }; if (form != null) { form.Say("Writing UVs - " + node.Name); } MDL0UVData *header = (MDL0UVData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x40; header->_dataOffset = 0x40; header->_index = index++; header->_format = (int)c._type; header->_divisor = (byte)c._scale; header->_isST = 1; header->_entryStride = (byte)c._dstStride; header->_numEntries = (ushort)c._dstCount; header->_min = (Vector2)c._min; header->_max = (Vector2)c._max; header->_pad1 = header->_pad2 = header->_pad3 = header->_pad4 = 0; c.Write(pData + 0x40); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._uvGroup.AddChild(node, false); pData += header->_dataLen; } } //Clean groups if (model._vertList != null && model._vertList.Count > 0) { model._children.Add(model._vertGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._vertGroup.Name)] = model._vertGroup; } else { model.UnlinkGroup(model._vertGroup); } if (model._normList != null && model._normList.Count > 0) { model._children.Add(model._normGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._normGroup.Name)] = model._normGroup; } else { model.UnlinkGroup(model._normGroup); } if (model._uvList != null && model._uvList.Count > 0) { model._children.Add(model._uvGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._uvGroup.Name)] = model._uvGroup; } else { model.UnlinkGroup(model._uvGroup); } if (model._colorList != null && model._colorList.Count > 0) { model._children.Add(model._colorGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._colorGroup.Name)] = model._colorGroup; } else { model.UnlinkGroup(model._colorGroup); } //Link sets if (model._objList != null) { foreach (MDL0ObjectNode poly in model._objList) { if (poly._elementIndices[0] != -1 && model._vertList != null && model._vertList.Count > poly._elementIndices[0]) { poly._vertexNode = (MDL0VertexNode)model._vertGroup._children[poly._elementIndices[0]]; } if (poly._elementIndices[1] != -1 && model._normList != null && model._normList.Count > poly._elementIndices[1]) { poly._normalNode = (MDL0NormalNode)model._normGroup._children[poly._elementIndices[1]]; } for (int i = 2; i < 4; i++) { if (poly._elementIndices[i] != -1 && model._colorList != null && model._colorList.Count > poly._elementIndices[i]) { poly._colorSet[i - 2] = (MDL0ColorNode)model._colorGroup._children[poly._elementIndices[i]]; } } for (int i = 4; i < 12; i++) { if (poly._elementIndices[i] != -1 && model._uvList != null && model._uvList.Count > poly._elementIndices[i]) { poly._uvSet[i - 4] = (MDL0UVNode)model._uvGroup._children[poly._elementIndices[i]]; } } } } }
///<summary> ///Open a file based on the filename ///</summary> /// <param name="filename"> Filename of file to open</param> public void openFile(string filename) { if (!filename.EndsWith(".mta") && !filename.EndsWith(".dat") && !filename.EndsWith(".smd")) { openAnimation(filename); } if (filename.EndsWith(".vbn")) { Runtime.TargetVBN = new VBN(filename); if (Directory.Exists("Skapon\\")) { NUD nud = Skapon.Create(Runtime.TargetVBN); ModelContainer con = new ModelContainer(); con.vbn = Runtime.TargetVBN; con.nud = nud; nud.PreRender(); Runtime.ModelContainers.Add(con); } } if (filename.EndsWith(".sb")) { SB sb = new SB(); sb.Read(filename); SwagEditor swagEditor = new SwagEditor(sb) { ShowHint = DockState.DockRight }; AddDockedControl(swagEditor); SwagEditors.Add(swagEditor); } if (filename.EndsWith(".dat")) { if (filename.EndsWith("AJ.dat")) { MessageBox.Show("This is animation; load with Animation -> Import"); return; } DAT dat = new DAT(); dat.Read(new FileData(filename)); ModelContainer c = new ModelContainer(); Runtime.ModelContainers.Add(c); c.dat_melee = dat; dat.PreRender(); HashMatch(); Runtime.TargetVBN = dat.bones; DAT_TreeView p = new DAT_TreeView() { ShowHint = DockState.DockLeft }; p.setDAT(dat); AddDockedControl(p); //Runtime.TargetVBN = dat.bones; meshList.refresh(); } if (filename.EndsWith(".nut")) { Runtime.TextureContainers.Add(new NUT(filename)); NUTEditor ev = new NUTEditor(); ev.Show(); } if (filename.EndsWith(".lvd")) { Runtime.TargetLVD = new LVD(filename); LVD test = Runtime.TargetLVD; lvdList.fillList(); } if (filename.EndsWith(".mta")) { Runtime.TargetMTA = new MTA(); Runtime.TargetMTA.Read(filename); viewports[0].loadMTA(Runtime.TargetMTA); MTAEditor temp = new MTAEditor(Runtime.TargetMTA) { ShowHint = DockState.DockLeft }; temp.Text = Path.GetFileName(filename); AddDockedControl(temp); mtaEditors.Add(temp); } if (filename.EndsWith(".mtable")) { //project.openACMD(filename); Runtime.Moveset = new MovesetManager(filename); } if (filename.EndsWith("path.bin")) { Runtime.TargetPath = new PathBin(filename); } else if (filename.EndsWith(".bin")) { //Note to whoever is readin this: //Eventually we need to look at the magic here (and also make all .bins look at magic) //Runtime.TargetCMR0 = new CMR0(); //Runtime.TargetCMR0.read(new FileData(filename)); PARAMEditor p = new PARAMEditor(filename) { ShowHint = DockState.Document }; p.Text = Path.GetFileName(filename); AddDockedControl(p); paramEditors.Add(p); } if (filename.EndsWith(".mdl0")) { MDL0Bones mdl0 = new MDL0Bones(); Runtime.TargetVBN = mdl0.GetVBN(new FileData(filename)); } if (filename.EndsWith(".smd")) { Runtime.TargetVBN = new VBN(); SMD.read(filename, new SkelAnimation(), Runtime.TargetVBN); } if (filename.ToLower().EndsWith(".dae")) { DAEImportSettings m = new DAEImportSettings(); m.ShowDialog(); if (m.exitStatus == DAEImportSettings.Opened) { if (Runtime.ModelContainers.Count < 1) { Runtime.ModelContainers.Add(new ModelContainer()); } Collada.DAEtoNUD(filename, Runtime.ModelContainers[0]); // apply settings m.Apply(Runtime.ModelContainers[0].nud); Runtime.ModelContainers[0].nud.MergePoly(); meshList.refresh(); } } if (filename.EndsWith(".mbn")) { MBN m = new MBN(); m.Read(filename); ModelContainer con = new ModelContainer(); BCH b = new BCH(); con.bch = b; b.mbn = m; b.Read("C:\\s\\Smash\\extract\\data\\fighter\\lucas\\Ness3DS - h00\\normal.bch"); Runtime.ModelContainers.Add(con); } /*if (filename.EndsWith(".bch")) * { * ModelContainer con = new ModelContainer(); * BCH b = new BCH(); * b.Read(filename); * con.bch = b; * Runtime.ModelContainers.Add(con); * }*/ if (filename.EndsWith(".nud")) { openNud(filename); } if (filename.EndsWith(".moi")) { MOI moi = new MOI(filename); AddDockedControl(new MOIEditor(moi) { ShowHint = DockState.DockRight }); } if (filename.EndsWith(".wrkspc")) { Workspace = new WorkspaceManager(project); Workspace.OpenWorkspace(filename); } if (Runtime.TargetVBN != null) { ModelContainer m = new ModelContainer(); m.vbn = Runtime.TargetVBN; Runtime.ModelContainers.Add(m); if (filename.EndsWith(".smd")) { m.nud = SMD.toNUD(filename); meshList.refresh(); } leftPanel.treeRefresh(); } else { foreach (ModelContainer m in Runtime.ModelContainers) { if (m.vbn != null) { Runtime.TargetVBN = Runtime.ModelContainers[0].vbn; break; } } } // Don't want to mess up the project tree if we // just set it up already if (!filename.EndsWith(".wrkspc")) { project.fillTree(); } }
internal static unsafe void Build(Collada form, ModelLinker linker, MDL0Header *header, int length, bool force) { byte *groupAddr = (byte *)header + linker._headerLen + linker._tableLen; byte *dataAddr = groupAddr + linker._groupLen + linker._texLen; //Definitions start here byte *assetAddr = dataAddr + linker._defLen + linker._boneLen + linker._dataLen; linker.Header = header; if (form != null) { form.Say("Writing header..."); } //Create new model header *header = new MDL0Header(length, linker.Version); MDL0Props *props = header->Properties; if (form != null) { form.Say("Writing node table..."); } //Write node table, assign node ids WriteNodeTable(linker); if (form != null) { form.Say("Writing definitions..."); } //Write def table WriteDefs(linker, ref groupAddr, ref dataAddr); //Set format list for each polygon's UVAT groups SetFormatLists(linker); //Write assets first, but only if the model is an import if (linker.Model._isImport) { WriteAssets(form, linker, ref assetAddr); } //Write groups linker.Write(form, ref groupAddr, ref dataAddr, force); //Write Part2 Entries if (linker.Model._part2Entries.Count > 0 && linker.Version != 9) { header->_part2Offset = (int)dataAddr - (int)header; Part2Data *part2 = header->Part2; if (part2 != null) { part2->_totalLen = 0x1C + linker.Model._part2Entries.Count * 0x2C; ResourceGroup *pGroup = part2->Group; *pGroup = new ResourceGroup(linker.Model._part2Entries.Count); ResourceEntry *pEntry = &pGroup->_first + 1; byte * pData = (byte *)pGroup + pGroup->_totalSize; foreach (string s in linker.Model._part2Entries) { (pEntry++)->_dataOffset = (int)pData - (int)pGroup; Part2DataEntry *p = (Part2DataEntry *)pData; *p = new Part2DataEntry(1); pData += 0x1C; } } } else { header->_part2Offset = 0; } //Write textures WriteTextures(linker, ref groupAddr); //Set box min and box max if (linker.Model._isImport) { SetBox(linker); } //Store group offsets linker.Finish(); //Set new properties *props = new MDL0Props(linker.Version, linker.Model._numVertices, linker.Model._numFaces, linker.Model._numNodes, linker.Model._unk1, linker.Model._unk2, linker.Model._unk3, linker.Model._unk4, linker.Model._unk5, linker.Model._unk6, linker.Model.BoxMin, linker.Model.BoxMax); }
public void Apply(Nud nud) { Matrix4 rotXBy90 = Matrix4.CreateRotationX(0.5f * (float)Math.PI); float scale = 1f; bool hasScale = float.TryParse(scaleTB.Text, out scale); bool checkedMeshName = false; bool fixMeshName = false; bool hasShownShadowWarning = false; foreach (Nud.Mesh mesh in nud.Nodes) { if (BoneTypes[(string)boneTypeComboBox.SelectedItem] == BoneTypes["None"]) { mesh.boneflag = 0; } if (!checkedMeshName) { checkedMeshName = true; if (Collada.HasInitialUnderscoreId(mesh.Text)) { fixMeshName = DialogResult.Yes == MessageBox.Show("Detected mesh names that start with \"_###_\". Would you like to fix this?\nIt is recommended that you select \"Yes\".", "Mesh Name Fix", MessageBoxButtons.YesNo); } } if (fixMeshName) { mesh.Text = Collada.RemoveInitialUnderscoreId(mesh.Text); } foreach (Nud.Polygon poly in mesh.Nodes) { if (BoneTypes[(string)boneTypeComboBox.SelectedItem] == BoneTypes["None"]) { poly.polflag = 0; } if (smoothNrmCB.Checked) { poly.SmoothNormals(); } // Set the vertex size before tangent/bitangent calculations. if (poly.vertSize == (int)Nud.Polygon.VertexTypes.NormalsHalfFloat) // what is this supposed to mean? { poly.vertSize = 0; } else { poly.vertSize = BoneTypes[(string)boneTypeComboBox.SelectedItem] | VertexTypes[(string)vertTypeComboBox.SelectedItem]; } poly.CalculateTangentBitangent(); int vertSizeShadowWarning = (int)Nud.Polygon.BoneTypes.HalfFloat | (int)Nud.Polygon.VertexTypes.NormalsTanBiTanHalfFloat; if (!hasShownShadowWarning && poly.vertSize == vertSizeShadowWarning) { MessageBox.Show("Using \"" + (string)boneTypeComboBox.SelectedItem + "\" and \"" + (string)vertTypeComboBox.SelectedItem + "\" can make shadows not appear in-game.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); hasShownShadowWarning = true; } if (stageMatCB.Checked) { poly.materials.Clear(); poly.materials.Add(Nud.Material.GetStageDefault()); } foreach (Nud.Vertex v in poly.vertices) { //Scroll UVs V by -1 if (transUvVerticalCB.Checked) { for (int i = 0; i < v.uv.Count; i++) { v.uv[i] = new Vector2(v.uv[i].X, v.uv[i].Y + 1); } } // Flip UVs if (flipUVCB.Checked) { for (int i = 0; i < v.uv.Count; i++) { v.uv[i] = new Vector2(v.uv[i].X, 1 - v.uv[i].Y); } } // Halve vertex colors if (vertColorDivCB.Checked) { for (int i = 0; i < 3; i++) { v.color[i] = v.color[i] / 2; } } // Set vertex colors to white. if (vertcolorCB.Checked) { v.color = new Vector4(127, 127, 127, 127); } // Rotate 90 degrees. if (rotate90CB.Checked) { v.pos = Vector3.TransformPosition(v.pos, rotXBy90); v.nrm = Vector3.TransformNormal(v.nrm, rotXBy90); } // Scale. if (scale != 1f) { v.pos = Vector3.Multiply(v.pos, scale); } } } } // Wait until after the model is rotated. nud.GenerateBoundingSpheres(); }
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)); }