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;
        }
Esempio n. 2
0
        public GLMaterial(GLModel model, MDL0MaterialNode mat)
        {
            _model = model;

            foreach (MDL0MaterialRefNode r in mat.Children)
            {
                _textureRefs.Add(new GLTextureRef(this, r));
            }
        }
Esempio n. 3
0
        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();
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 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);
        }
Esempio n. 8
0
        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));
        }
Esempio n. 9
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));
        }
Esempio n. 10
0
 private static void WriteMaterial(StreamWriter writer, MDL0MaterialNode mat)
 {
     writer.WriteLine($"usemtl {mat.Name}");
 }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }