public override bool OnInitialize() { MDL0TextureRef* header = Header; _texPtr = header->_texPtr; _pltPtr = header->_pltPtr; _index1 = header->_index1; _index2 = header->_index2; _uWrap = header->_uWrap; _vWrap = header->_vWrap; _minFltr = header->_minFltr; _magFltr = header->_magFltr; _lodBias = header->_lodBias; _maxAniso = header->_maxAniso; _clampBias = header->_clampBias == 1; _texelInterp = header->_texelInterp == 1; _pad = header->_pad; if (header->_texOffset != 0) { if (_replaced && header->_texOffset >= Parent.WorkingUncompressed.Length) Name = null; else { if (_replaced) Name = header->TextureName; else _name = header->TextureName; _texture = Model.FindOrCreateTexture(_name); _texture._references.Add(this); } } if (header->_pltOffset != 0) { if (_replaced && header->_pltOffset >= Parent.WorkingUncompressed.Length) _palette = null; else { string name = header->PaletteName; _palette = Model.FindOrCreatePalette(name); _palette._references.Add(this); } } int len = ((MDL0MaterialNode)Parent).XFCommands.Length; if (len != 0 && Index * 2 < len) { TexMtxFlags = new XFTexMtxInfo(((MDL0MaterialNode)Parent).XFCommands[Index * 2].values[0]); DualTexFlags = new XFDualTex(((MDL0MaterialNode)Parent).XFCommands[Index * 2 + 1].values[0]); getValues(); } //if (PaletteNode == null && TextureNode != null) //{ // if (TextureNode.Source == null) // TextureNode.GetSource(); // if (TextureNode.Source is TEX0Node && ((TEX0Node)TextureNode.Source).HasPalette) // { // Model._errors.Add("A palette was not set to texture reference " + Index + " in material " + Parent.Index + " (" + Parent.Name + ")."); // PaletteNode = Model.FindOrCreatePalette(TextureNode.Name); // SignalPropertyChange(); // } //} MDL0TexSRTData* TexSettings = ((MDL0MaterialNode)Parent).Header->TexMatrices(((MDL0MaterialNode)Parent)._initVersion); _texFlags = TexSettings->GetTexFlags(Index); _texMatrix = TexSettings->GetTexMatrices(Index); _flags = (TexFlags)((((MDL0MaterialNode)Parent)._layerFlags >> (4 * Index)) & 0xF); _bindState = new FrameState( new Vector3(_texFlags.TexScale._x, _texFlags.TexScale._y, 1), new Vector3(_texFlags.TexRotation, 0, 0), new Vector3(_texFlags.TexTranslation._x, _texFlags.TexTranslation._y, 0)); return false; }
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; }