protected override bool OnInitialize()
        {
            MDL0Material *header = Header;

            if ((_name == null) && (header->_stringOffset != 0))
            {
                _name = header->ResourceString;
            }

            _numTextures = header->_flag1;
            _numLayers   = header->_numLayers;
            _unk1        = header->_unk1;
            _unk3        = header->_unk3;
            _unk4        = header->_unk4;
            _unk6        = header->_unk6;
            _flag3       = header->_flag3;
            _flag4       = header->_flag4;
            _flag5       = header->_flag5;
            _flag6       = header->_flag6;
            _flag7       = header->_flag7;
            _flag8       = header->_flag8;
            _type        = header->_type;

            MatModeBlock *mode = header->DisplayLists;

            _alphaFunc     = mode->AlphaFunction;
            _zMode         = mode->ZMode;
            _blendMode     = mode->BlendMode;
            _constantAlpha = mode->ConstantAlpha;

            MDL0Data7Part4 *part4 = header->Part4;

            if (part4 != null)
            {
                ResourceGroup *group = part4->Group;
                for (int i = 0; i < group->_numEntries; i++)
                {
                    _part4Entries.Add(group->First[i].GetName());
                }
            }

            _children = new List <ResourceNode>();
            OnPopulate();
            return(true);
        }
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            MDL0Material* header = (MDL0Material*)address;

            ushort i1 = 0x1040, i2 = 0x1050; int mtx = 0;

            //Set offsets
            header->_dataLen = _dataLen = length;

            int addr = 0;
            if (Model._version >= 10)
            {
                header->_dlOffset = 0; //Fur Data not supported
                header->_dlOffsetv10p = length - 0x180;
                if (Children.Count > 0)
                    header->_matRefOffset = addr = 1048;
                else
                    header->_matRefOffset = 0;
            }
            else
            {
                header->_dlOffset = length - 0x180;
                if (Children.Count > 0)
                    header->_matRefOffset = addr = 1044;
                else
                    header->_matRefOffset = 0;
            }

            //Check for user entries
            if (_userEntries.Count > 0)
            {
                addr += Children.Count * 0x34;
                if (Model._version == 11 || Model._version == 10)
                    header->_dlOffset = addr;
                else
                    header->_userDataOffset = addr;

                _userEntries.Write(header->UserData(Model._version));
            }
            else
                addr = header->_userDataOffset = 0;

            //Set defaults if the model is an import or the material was created
            if (Model._isImport || New)
            {
                if (New)
                {
                    _lSet = 20;
                    _fSet = 4;
                    _ssc = 3;

                    C1ColorEnabled = true;
                    C1AlphaMaterialSource = GXColorSrc.Vertex;
                    C1ColorMaterialSource = GXColorSrc.Vertex;
                    C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                    C1ColorAttenuation = GXAttnFn.Spotlight;
                    C1AlphaEnabled = true;
                    C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                    C1AlphaAttenuation = GXAttnFn.Spotlight;

                    C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                    C2ColorAttenuation = GXAttnFn.None;
                    C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                    C2AlphaAttenuation = GXAttnFn.None;
                }

                //Set default texgen flags
                for (int i = 0; i < Children.Count; i++)
                {
                    MDL0MaterialRefNode node = ((MDL0MaterialRefNode)Children[i]);

                    //Tex Mtx
                    XFData dat = new XFData();
                    dat.addr = (XFMemoryAddr)i1++;
                    XFTexMtxInfo tex = new XFTexMtxInfo();
                    tex._data = (uint)(0 |
                        ((int)TexProjection.ST << 1) |
                        ((int)TexInputForm.AB11 << 2) |
                        ((int)TexTexgenType.Regular << 4) |
                        ((int)(0x5) << 7) |
                        (4 << 10) |
                        (2 << 13));
                    dat.values.Add(tex._data);
                    XFCmds.Add(dat);
                    node.TexMtxFlags = tex;

                    //Dual Tex
                    dat = new XFData();
                    dat.addr = (XFMemoryAddr)i2++;
                    XFDualTex dtex = new XFDualTex(mtx, 0); mtx += 3;
                    dat.values.Add(dtex.Value);
                    XFCmds.Add(dat);
                    node.DualTexFlags = dtex;
                    node.getValues();
                    node._texFlags.TexScale = new Vector2(1);
                    node._bindState._scale = new Vector3(1);
                    node._texMatrix.TexMtx = Matrix43.Identity;
                    node._texMatrix.SCNCamera = -1;
                    node._texMatrix.SCNLight = -1;
                    node._texMatrix.MapMode = 0;
                    node._texMatrix.Identity = 1;
                }
            }

            //Set header values
            header->_numTextures = Children.Count;
            header->_numTexGens = _numTextures = (byte)Children.Count;
            header->_index = Index;
            header->_numLightChans = _numLights;
            header->_activeTEVStages = (byte)_ssc;
            header->_numIndTexStages = _clip;
            header->_enableAlphaTest = _transp;

            header->_lightSet = _lSet;
            header->_fogSet = _fSet;
            header->_pad = 0;

            header->_cull = (int)_cull;
            header->_usageFlags = _usageFlags._data;

            header->_indirectMethod1 = _indirectMethod1;
            header->_indirectMethod2 = _indirectMethod2;
            header->_indirectMethod3 = _indirectMethod3;
            header->_indirectMethod4 = _indirectMethod4;

            header->_normMapRefLight1 = _normMapRefLight1;
            header->_normMapRefLight2 = _normMapRefLight2;
            header->_normMapRefLight3 = _normMapRefLight3;
            header->_normMapRefLight4 = _normMapRefLight4;

            //Generate layer flags and write texture matrices
            MDL0TexSRTData* TexSettings = header->TexMatrices(Model._version);
            *TexSettings = MDL0TexSRTData.Default;

            _layerFlags = 0;
            for (int i = Children.Count - 1; i >= 0; i--)
            {
                MDL0MaterialRefNode node = (MDL0MaterialRefNode)Children[i];

                node._flags |= TexFlags.Enabled;

                node._texFlags.TexScale = new Vector2(node._bindState._scale._x, node._bindState._scale._y);
                node._texFlags.TexRotation = node._bindState._rotate._x;
                node._texFlags.TexTranslation = new Vector2(node._bindState._translate._x, node._bindState._translate._y);

                //Check for non-default values
                if (node._texFlags.TexScale != new Vector2(1))
                    node._flags &= 0xF - TexFlags.FixedScale;
                else
                    node._flags |= TexFlags.FixedScale;

                if (node._texFlags.TexRotation != 0)
                    node._flags &= 0xF - TexFlags.FixedRot;
                else
                    node._flags |= TexFlags.FixedRot;

                if (node._texFlags.TexTranslation != new Vector2(0))
                    node._flags &= 0xF - TexFlags.FixedTrans;
                else
                    node._flags |= TexFlags.FixedTrans;

                TexSettings->SetTexFlags(node._texFlags, node.Index);
                TexSettings->SetTexMatrices(node._texMatrix, node.Index);

                _layerFlags = ((_layerFlags << 4) | (byte)node._flags);
            }

            TexSettings->_layerFlags = _layerFlags;
            TexSettings->_mtxFlags = _texMtxFlags;

            //Write lighting flags
            MDL0MaterialLighting* Light = header->Light(Model._version);

            Light->Channel1 = _chan1;
            Light->Channel2 = _chan2;

            //The shader offset will be written later

            //Rebuild references
            MDL0TextureRef* mRefs = header->First;
            foreach (MDL0MaterialRefNode n in Children)
                n.Rebuild(mRefs++, 0x34, force);

            //Set Display Lists
            *header->TevKonstBlock(Model._version) = _tevKonstBlock;
            *header->TevColorBlock(Model._version) = _tevColorBlock;
            *header->IndMtxBlock(Model._version) = _indMtx;

            mode = header->DisplayLists(Model._version);
            *mode = MatModeBlock.Default;
            if (Model._isImport)
            {
                _alphaFunc = mode->AlphaFunction;
                _zMode = mode->ZMode;
                _blendMode = mode->BlendMode;
                _constantAlpha = mode->ConstantAlpha;
            }
            else
            {
                mode->AlphaFunction = _alphaFunc;
                mode->ZMode = _zMode;
                mode->BlendMode = _blendMode;
                mode->ConstantAlpha = _constantAlpha;
            }

            //Write XF flags
            byte* xfData = (byte*)header->DisplayLists(Model._version) + 0xE0;
            i1 = 0x1040; i2 = 0x1050; mtx = 0;
            foreach (MDL0MaterialRefNode mr in Children)
            {
                //Tex Mtx
                *xfData++ = 0x10;
                *(bushort*)xfData = 0; xfData += 2;
                *(bushort*)xfData = (ushort)i1++;  xfData += 2;
                *(buint*)xfData = mr.TexMtxFlags._data; xfData += 4;

                //Dual Tex
                *xfData++ = 0x10;
                *(bushort*)xfData = 0; xfData += 2;
                *(bushort*)xfData = (ushort)i2++; xfData += 2;
                *(buint*)xfData = new XFDualTex(mtx, mr.DualTexFlags.NormalEnable).Value; xfData += 4;

                mtx += 3;
            }

            New = false;
        }
        public override bool OnInitialize()
        {
            MDL0Material* header = Header;

            _initVersion = header->_pad != 0 && _replaced ? header->_pad : Model._version;

            if ((_name == null) && (header->_stringOffset != 0))
                _name = header->ResourceString;

            XFCmds.Clear();

            //Get XF Commands
            byte* pData = (byte*)header->DisplayLists(Model._version) + 0xE0;
            Top:
            if (*pData++ == 0x10)
            {
                XFData dat = new XFData();
                int count = (ushort)*(bushort*)pData; pData += 2;
                dat.addr = (XFMemoryAddr)(ushort)*(bushort*)pData; pData += 2;
                dat.values = new List<uint>();
                for (int i = 0; i < count + 1; i++)
                {
                    dat.values.Add(*(buint*)pData);
                    pData += 4;
                }
                XFCmds.Add(dat);
                goto Top;
            }

            _mdl0Offset = header->_mdl0Offset;
            _stringOffset = header->_stringOffset;
            _userDataOffset = header->UserDataOffset(_initVersion);
            _shaderOffset = header->_shaderOffset;
            _dlOffset = header->DisplayListOffset(_initVersion);
            _furDataOffset = header->FurDataOffset(_initVersion);
            _matRefOffset = header->_matRefOffset;
            _pad = header->_pad;

            _dataLen = header->_dataLen;
            _numTextures = header->_numTexGens;
            _numLights = header->_numLightChans;
            _usageFlags = new Bin32(header->_usageFlags);

            _indirectMethod1 = header->_indirectMethod1;
            _indirectMethod2 = header->_indirectMethod2;
            _indirectMethod3 = header->_indirectMethod3;
            _indirectMethod4 = header->_indirectMethod4;

            _normMapRefLight1 = header->_normMapRefLight1;
            _normMapRefLight2 = header->_normMapRefLight2;
            _normMapRefLight3 = header->_normMapRefLight3;
            _normMapRefLight4 = header->_normMapRefLight4;

            _ssc = header->_activeTEVStages;
            _clip = header->_numIndTexStages;
            _transp = header->_enableAlphaTest;

            _lSet = header->_lightSet;
            _fSet = header->_fogSet;

            _cull = (CullMode)(int)header->_cull;

            if ((-header->_mdl0Offset + (int)header->DisplayListOffset(_initVersion)) % 0x20 != 0)
            {
                Model._errors.Add("Material " + Index + " has an improper align offset.");
                SignalPropertyChange();
            }

            mode = header->DisplayLists(_initVersion);
            _alphaFunc = mode->AlphaFunction;
            _zMode = mode->ZMode;
            _blendMode = mode->BlendMode;
            _constantAlpha = mode->ConstantAlpha;

            _tevColorBlock = *header->TevColorBlock(_initVersion);
            _tevKonstBlock = *header->TevKonstBlock(_initVersion);
            _indMtx = *header->IndMtxBlock(_initVersion);

            MDL0TexSRTData* TexMatrices = header->TexMatrices(_initVersion);

            _layerFlags = TexMatrices->_layerFlags;
            _texMtxFlags = TexMatrices->_mtxFlags;

            MDL0MaterialLighting* Light = header->Light(_initVersion);

            (_chan1 = Light->Channel1)._parent = this;
            (_chan2 = Light->Channel2)._parent = this;

            c1 = CReg2Color;
            c2 = CReg2Color;
            c3 = CReg2Color;

            k1 = KReg0Color;
            k2 = KReg1Color;
            k3 = KReg2Color;
            k3 = KReg3Color;

            clr1 = C1MaterialColor;
            clr2 = C2MaterialColor;

            amb1 = C1AmbientColor;
            amb2 = C2AmbientColor;

            (_userEntries = new UserDataCollection()).Read(header->UserData(_initVersion));

            return true;
        }