private void ExportShader() { MDL0MaterialNode mat = _resource as MDL0MaterialNode; ShaderGenerator.Set(mat); ShaderGenerator.PixelLighting = MessageBox.Show(MainForm.Instance, "Use per-pixel lighting?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes; SaveFileDialog s = new SaveFileDialog(); s.Filter = "Text File (*.txt)|*.txt"; s.FileName = _resource.Name + " vertex shader"; s.Title = "Choose a place to save the vertex shader"; if (s.ShowDialog() == DialogResult.OK) { System.IO.File.WriteAllText(s.FileName, ShaderGenerator.GenVertexShader().Replace("\n", Environment.NewLine)); } s.Filter = "Text File (*.txt)|*.txt"; s.FileName = _resource.Name + " fragment shader"; s.Title = "Choose a place to save the fragment shader"; if (s.ShowDialog() == DialogResult.OK) { string m = ShaderGenerator.GenMaterialFragShader(); string[] t = ShaderGenerator.GenTEVFragShader(); System.IO.File.WriteAllText(s.FileName, ShaderGenerator.CombineFragShader(m, t, mat.ActiveShaderStages).Replace("\n", Environment.NewLine)); } ShaderGenerator.Clear(); ShaderGenerator._pixelLightingChanged = false; }
public GLMaterial(GLModel model, MDL0MaterialNode mat) { _model = model; foreach (MDL0MaterialRefNode r in mat.Children) { _textureRefs.Add(new GLTextureRef(this, r)); } }
public void NewMaterial() { if (_modelViewerOpen) { return; } MDL0Node model = ((MDL0Node)_resource); if (model._matGroup == null) { MDL0GroupNode g = model._matGroup; if (g == null) { model.AddChild(g = new MDL0GroupNode(MDLResourceType.Materials), true); model._matGroup = g; model._matList = g.Children; } } MDL0MaterialNode mat = new MDL0MaterialNode(); model._matGroup.AddChild(mat); mat.Name = "Material" + mat.Index; mat.New = true; if (model._shadGroup == null) { MDL0GroupNode g = model._shadGroup; if (g == null) { model.AddChild(g = new MDL0GroupNode(MDLResourceType.Shaders), true); model._shadGroup = g; model._shadList = g.Children; } } if (model._shadList.Count == 0) { NewShader(); } mat.ShaderNode = (MDL0ShaderNode)model._shadList[0]; mat.AddChild(new MDL0MaterialRefNode() { Name = "MatRef0" }); mat.Rebuild(true); BaseWrapper b = FindResource(mat, true); if (b != null) { b.EnsureVisible(); } }
public MDL0MaterialNode NewMaterial() { MDL0Node model = (MDL0Node)_resource; if (model._matGroup == null) { MDL0GroupNode g = model._matGroup; if (g == null) { model.AddChild(g = new MDL0GroupNode(MDLResourceType.Materials), true); model._matGroup = g; model._matList = g.Children; } } MDL0MaterialNode mat = new MDL0MaterialNode(); model._matGroup.AddChild(mat); mat.Name = "Material" + mat.Index; if (model._shadGroup == null) { MDL0GroupNode g = model._shadGroup; if (g == null) { model.AddChild(g = new MDL0GroupNode(MDLResourceType.Shaders), true); model._shadGroup = g; model._shadList = g.Children; } } if (model._shadList.Count == 0) { NewShader(); } mat.ShaderNode = (MDL0ShaderNode)model._shadList[0]; MDL0MaterialRefNode mr = new MDL0MaterialRefNode(); mat.AddChild(mr); mr.Name = "MatRef0"; mat.Rebuild(true); BaseWrapper b = FindResource(mat, true); b?.EnsureVisible(); return(mat); }
private static void WriteMaterial(StreamWriter writer, MDL0MaterialNode mat) { writer.WriteLine(String.Format("usemtl {0}", mat.Name)); }
private void FinishMDL0(MDL0Node model) { Error = "There was a problem creating a default material and shader."; if (model._matList.Count == 0 && model._objList.Count != 0) { MDL0MaterialNode mat = new MDL0MaterialNode() { _name = "Default", }; (mat.ShaderNode = new MDL0ShaderNode()).AddChild(new MDL0TEVStageNode() { RasterColor = ColorSelChan.LightChannel0, AlphaSelectionD = AlphaArg.RasterAlpha, ColorSelectionD = ColorArg.RasterColor, }); model._shadGroup.AddChild(mat.ShaderNode); model._matGroup.AddChild(mat); foreach (MDL0ObjectNode obj in model._objList) { if (obj._drawCalls.Count == 0) { obj._drawCalls.Add(new DrawCall(obj)); } obj._drawCalls[0].MaterialNode = mat; } } Error = "There was a problem removing original color buffers."; //Remove original color buffers if option set if (_importOptions._ignoreColors) { if (model._objList != null && model._objList.Count != 0) { foreach (MDL0ObjectNode p in model._objList) { for (int x = 2; x < 4; x++) { if (p._manager._faceData[x] != null) { p._manager._faceData[x].Dispose(); p._manager._faceData[x] = null; } } } } } Error = "There was a problem adding default color values."; //Add color buffers if option set if (_importOptions._addClrs) { RGBAPixel pixel = _importOptions._dfltClr; //Add a color buffer to objects that don't have one if (model._objList != null && model._objList.Count != 0) { foreach (MDL0ObjectNode p in model._objList) { if (p._manager._faceData[2] == null) { RGBAPixel *pIn = (RGBAPixel *)(p._manager._faceData[2] = new UnsafeBuffer(4 * p._manager._pointCount)).Address; for (int i = 0; i < p._manager._pointCount; i++) { *pIn++ = pixel; } } } } } Error = "There was a problem initializing materials."; //Apply defaults to materials if (model._matList != null) { foreach (MDL0MaterialNode mat in model._matList) { mat._activeStages = mat.ShaderNode.Stages; if (_importOptions._mdlType == ImportOptions.MDLType.Stage) { mat._lightSetIndex = 0; mat._fogIndex = 0; } } } Error = "There was a problem remapping materials."; //Remap materials if option set if (_importOptions._rmpMats && model._matList != null && model._objList != null) { foreach (MDL0ObjectNode obj3 in model._objList) { MDL0MaterialNode mat = obj3._drawCalls[0].MaterialNode; foreach (MDL0MaterialNode m in model._matList) { if (m.Children.Count > 0 && m.Children[0] != null && mat != null && mat.Children.Count > 0 && mat.Children[0] != null && m.Children[0].Name == mat.Children[0].Name && m.C1ColorMaterialSource == mat.C1ColorMaterialSource) { obj3._drawCalls[0].MaterialNode = m; break; } } } //Remove unused materials for (int i = 0; i < model._matList.Count; i++) { if (((MDL0MaterialNode)model._matList[i])._objects.Count == 0) { model._matList.RemoveAt(i--); } } } Error = "There was a problem writing the model."; //Clean the model and then build it! if (model != null) { model.FinishImport(); } }
public IModel ImportModel(string filePath, ImportType type) { IModel model = null; ModelType = type; BoneType = ModelType == ImportType.MDL0 ? typeof(MDL0BoneNode) : null; //TransformMatrix = Matrix.TransformMatrix(_importOptions._modifyScale, _importOptions._modifyRotation, new Vector3()); switch (type) { case ImportType.MDL0: MDL0Node m = new MDL0Node() { _name = Path.GetFileNameWithoutExtension(filePath), _version = _importOptions._modelVersion.Clamp(8, 11) }; if (_importOptions._setOrigPath) { m._originalPath = filePath; } m.BeginImport(); model = m; break; } CurrentModel = model; Error = "There was a problem reading the model."; using (DecoderShell shell = DecoderShell.Import(filePath)) try { Error = "There was a problem reading texture entries."; //Extract images, removing duplicates foreach (ImageEntry img in shell._images) { string name = img._path != null? Path.GetFileNameWithoutExtension(img._path) : img._name != null ? img._name : img._id; switch (type) { case ImportType.MDL0: img._node = ((MDL0Node)model).FindOrCreateTexture(name); break; } } Error = "There was a problem creating a default shader."; //Create a shader ResourceNode shader = null; switch (type) { case ImportType.MDL0: MDL0Node m = (MDL0Node)model; MDL0ShaderNode shadNode = new MDL0ShaderNode() { _ref0 = 0, _ref1 = -1, _ref2 = -1, _ref3 = -1, _ref4 = -1, _ref5 = -1, _ref6 = -1, _ref7 = -1, }; shadNode._parent = m._shadGroup; m._shadList.Add(shadNode); switch (_importOptions._mdlType) { case ImportOptions.MDLType.Character: for (int i = 0; i < 3; i++) { switch (i) { case 0: shadNode.AddChild(new MDL0TEVStageNode(0x28F8AF, 0x08F2F0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap0, TexCoordID.TexCoord0, ColorSelChan.LightChannel0, true)); break; case 1: shadNode.AddChild(new MDL0TEVStageNode(0x08FEB0, 0x081FF0, 0, TevKColorSel.ConstantColor1_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap7, TexCoordID.TexCoord7, ColorSelChan.LightChannel0, false)); break; case 2: shadNode.AddChild(new MDL0TEVStageNode(0x0806EF, 0x081FF0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap7, TexCoordID.TexCoord7, ColorSelChan.Zero, false)); break; } } break; case ImportOptions.MDLType.Stage: shadNode.AddChild(new MDL0TEVStageNode(0x28F8AF, 0x08F2F0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap0, TexCoordID.TexCoord0, ColorSelChan.LightChannel0, true)); break; } shader = shadNode; break; } Error = "There was a problem extracting materials."; //Extract materials foreach (MaterialEntry mat in shell._materials) { List <ImageEntry> imgEntries = new List <ImageEntry>(); //Find effect if (mat._effect != null) { foreach (EffectEntry eff in shell._effects) { if (eff._id == mat._effect) //Attach textures and effects to material { if (eff._shader != null) { foreach (LightEffectEntry l in eff._shader._effects) { if (l._type == LightEffectType.diffuse && l._texture != null) { string path = l._texture; foreach (EffectNewParam p in eff._newParams) { if (p._sid == l._texture) { path = p._sampler2D._url; if (!String.IsNullOrEmpty(p._sampler2D._source)) { foreach (EffectNewParam p2 in eff._newParams) { if (p2._sid == p._sampler2D._source) { path = p2._path; } } } } } foreach (ImageEntry img in shell._images) { if (img._id == path) { imgEntries.Add(img); break; } } } } } } } } switch (type) { case ImportType.MDL0: MDL0MaterialNode matNode = new MDL0MaterialNode(); MDL0Node m = (MDL0Node)model; matNode._parent = m._matGroup; m._matList.Add(matNode); matNode._name = mat._name != null ? mat._name : mat._id; matNode.ShaderNode = shader as MDL0ShaderNode; mat._node = matNode; matNode._cull = _importOptions._culling; foreach (ImageEntry img in imgEntries) { MDL0MaterialRefNode mr = new MDL0MaterialRefNode(); (mr._texture = img._node as MDL0TextureNode)._references.Add(mr); mr._name = mr._texture.Name; matNode._children.Add(mr); mr._parent = matNode; mr._minFltr = mr._magFltr = 1; mr._uWrap = mr._vWrap = (int)_importOptions._wrap; } break; } } Say("Extracting scenes..."); List <ObjectInfo> _objects = new List <ObjectInfo>(); ResourceNode boneGroup = null; switch (type) { case ImportType.MDL0: boneGroup = ((MDL0Node)model)._boneGroup; break; } //Extract bones and objects and create bone tree foreach (SceneEntry scene in shell._scenes) { foreach (NodeEntry node in scene._nodes) { EnumNode(node, boneGroup, scene, model, shell, _objects, TransformMatrix, Matrix.Identity); } } //Add root bone if there are no bones if (boneGroup.Children.Count == 0) { switch (type) { case ImportType.MDL0: MDL0BoneNode bone = new MDL0BoneNode(); bone.Scale = new Vector3(1); bone.RecalcBindState(false, false); bone._name = "TopN"; TempRootBone = bone; break; } } //Create objects foreach (ObjectInfo obj in _objects) { NodeEntry node = obj._node; string w = obj._weighted ? "" : "un"; string w2 = obj._weighted ? "\nOne or more vertices may not be weighted correctly." : ""; string n = node._name != null ? node._name : node._id; Error = String.Format("There was a problem decoding {0}weighted primitives for the object {1}.{2}", w, n, w2); Say(String.Format("Decoding {0}weighted primitives for {1}...", w, n)); obj.Initialize(model, shell); } //Finish switch (type) { case ImportType.MDL0: MDL0Node mdl0 = (MDL0Node)model; if (TempRootBone != null) { mdl0._boneGroup._children.Add(TempRootBone); TempRootBone._parent = mdl0._boneGroup; } FinishMDL0(mdl0); break; } } #if !DEBUG catch (Exception x) { MessageBox.Show("Cannot continue importing this model.\n" + Error + "\n\nException:\n" + x.ToString()); model = null; Close(); } #endif finally { //Clean up the mess we've made GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } CurrentModel = null; Error = null; return(model); }
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)); }
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)); }
private static void WriteMaterial(StreamWriter writer, MDL0MaterialNode mat) { writer.WriteLine($"usemtl {mat.Name}"); }
public static string GeneratePixelShader(MDL0ObjectNode obj) { Reset(); MDL0MaterialNode mat = obj.UsableMaterialNode; MDL0ShaderNode shader = mat.ShaderNode; //w("#version 330\n"); foreach (MDL0MaterialRefNode r in mat.Children) { w("uniform sampler2D Texture{0};", r.Index); } for (int i = 0; i < obj._uvSet.Length; i++) { if (obj._uvSet[i] != null) { w("in vec2 UVSet{0};", i); } } for (int i = 0; i < obj._colorSet.Length; i++) { if (obj._colorSet[i] != null) { w("in vec2 ColorSet{0};", i); } } w("out vec4 out_color;\n"); //w("uniform vec4 C1Amb;\n"); //w("uniform vec4 C2Amb;\n"); //w("uniform vec4 C1Mat;\n"); //w("uniform vec4 C2Mat;\n"); Start(); foreach (MDL0MaterialRefNode r in mat.Children) { if (r.TextureCoordId >= 0) { w("vec4 tex{0}col = texture2D(Texture{0}, UVSet{1}.st);\n", r.Index, r.TextureCoordId); } } //w("vec4 creg0 = vec4(0.0, 0.0, 0.0, 0.0);\n"); //w("vec4 creg1 = vec4(0.0, 0.0, 0.0, 0.0);\n"); //w("vec4 creg2 = vec4(0.0, 0.0, 0.0, 0.0);\n"); //w("vec4 prev = vec4(0.0, 0.0, 0.0, 0.0);\n"); //foreach (TEVStage stage in shader.Children) // if (stage.Index < mat.ActiveShaderStages) // w(stage.Write(mat, obj)); // else break; //if (shader._stages > 0) //{ // w("prev.rgb = {0};\n", tevCOutputTable[(int)((TEVStage)shader.Children[shader.Children.Count - 1]).ColorRegister]); // w("prev.a = {0};\n", tevAOutputTable[(int)((TEVStage)shader.Children[shader.Children.Count - 1]).AlphaRegister]); //} w("out_color = tex0col;"); Finish(); return(tempShader); }
public static string GenerateVertexShader(MDL0ObjectNode obj) { Reset(); MDL0MaterialNode mat = obj.UsableMaterialNode; MDL0ShaderNode shader = mat.ShaderNode; //w("#version 330\n"); bool[] data = new bool[12]; for (int i = 0; i < 12; i++) { data[i] = obj._manager._faceData[i] != null; } if (data[0]) { w("in vec3 Position;"); } if (data[1]) { w("in vec3 Normal;"); } for (int i = 0; i < 2; i++) { if (data[i + 2]) { w("in vec4 Color{0};", i); } } for (int i = 0; i < 8; i++) { if (data[i + 4]) { w("in vec2 UV{0};", i); } } w("uniform mat4 projection_matrix;"); w("uniform mat4 modelview_matrix;"); for (int i = 0; i < obj._uvSet.Length; i++) { if (obj._uvSet[i] != null) { w("out vec2 UVSet{0};", i); } } for (int i = 0; i < obj._colorSet.Length; i++) { if (obj._colorSet[i] != null) { w("out vec4 ColorSet{0};", i); } } Start(); w("gl_Position = projection_matrix * modelview_matrix * vec4(Position, 1.0);"); //w("gl_Normal = vec4(Normal, 1.0);\n"); for (int i = 0; i < obj._uvSet.Length; i++) { if (obj._uvSet[i] != null) { w("UVSet{0} = UV{0};", i); } } for (int i = 0; i < obj._colorSet.Length; i++) { if (obj._colorSet[i] != null) { w("ColorSet{0} = Color{0};", i); } } Finish(); return(tempShader); }
public override ResourceNode Duplicate(bool changeName) { if (_resource.Parent == null) { return(null); } string tempPath = Path.GetTempFileName(); _resource.Export(tempPath); // Initialize node in a way that will not cause crashes ResourceNode rNode2; switch (Resource.ResourceFileType) { case ResourceType.MDL0Color: rNode2 = new MDL0ColorNode(); break; case ResourceType.MDL0UV: rNode2 = new MDL0UVNode(); break; case ResourceType.MDL0Material: rNode2 = new MDL0MaterialNode(); break; case ResourceType.MDL0Shader: rNode2 = new MDL0ShaderNode(); break; case ResourceType.MDL0Texture: rNode2 = new MDL0TextureNode(); break; case ResourceType.MDL0Normal: rNode2 = new MDL0NormalNode(); break; case ResourceType.MDL0Bone: rNode2 = new MDL0BoneNode(); break; case ResourceType.MDL0Vertex: rNode2 = new MDL0VertexNode(); break; default: throw new NotSupportedException("Unsupported type for MDL0 Duplication"); } rNode2._name = _resource.Name; rNode2.Replace(tempPath); if (rNode2 == null) { MessageBox.Show("The node could not be duplicated correctly.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } // Remove the node from the parent temporarily rNode2.Remove(); // Set the name programatically (based on Windows' implementation) int index = _resource.Index; int n = 0; if (changeName) { while (_resource.Parent.FindChildrenByName(rNode2.Name).Length >= 1) { // Get the last index of the last duplicated node in order to place it after that one index = Math.Max(index, _resource.Parent.FindChildrenByName(rNode2.Name).Last().Index); // Set the name based on the number of duplicate nodes found rNode2.Name = $"{_resource.Name} ({++n})"; } } // Place the node in the same containing parent, after the last duplicated node. _resource.Parent.InsertChild(rNode2, true, index + 1); // Update name again in order to refresh things that need refreshing when name is updated rNode2.OnRenamed(); return(rNode2); }