public void Reload(MaterialAnim anim) { Name = anim.Name; FrameCount = anim.FrameCount; FrameRate = 60.0f; Loop = anim.Loop; if (anim.TextureNames != null) { TextureList = anim.TextureNames.Keys.ToList(); } if (anim.MaterialAnimDataList == null) { return; } AnimGroups.Clear(); foreach (var matAnim in anim.MaterialAnimDataList) { var group = new MaterialAnimGroup(); AnimGroups.Add(group); group.Name = matAnim.Name; //Get the material animation's texture pattern animation lists //Each sampler has their own info for (int i = 0; i < matAnim.PatternAnimInfos.Count; i++) { var patternInfo = matAnim.PatternAnimInfos[i]; //Get the curve index for animated indices int curveIndex = patternInfo.CurveIndex; //Get the base index for starting values int textureBaseIndex = matAnim.BaseDataList.Length > i ? matAnim.BaseDataList[i] : 0; //Make a new sampler track using step interpolation var samplerTrack = new SamplerTrack(); samplerTrack.InterpolationType = STInterpoaltionType.Step; samplerTrack.Sampler = patternInfo.Name; group.Tracks.Add(samplerTrack); if (curveIndex != -1) { BfresAnimations.GenerateKeys(samplerTrack, matAnim.Curves[curveIndex], true); } else //Use the base data and make a constant key { samplerTrack.KeyFrames.Add(new STKeyFrame(0, textureBaseIndex)); } } //Get the list of animated parameters for (int i = 0; i < matAnim.ParamAnimInfos.Count; i++) { ParamAnimGroup paramGroup = new ParamAnimGroup(); paramGroup.Name = matAnim.ParamAnimInfos[i].Name; group.SubAnimGroups.Add(paramGroup); var paramInfo = matAnim.ParamAnimInfos[i]; //Params have int and float curves int curveIndex = paramInfo.BeginCurve; int constantIndex = paramInfo.BeginConstant; int numFloats = paramInfo.FloatCurveCount; int numInts = paramInfo.IntCurveCount; int numConstants = paramInfo.ConstantCount; //Each constant and curve get's their own value using a value offset for (int j = 0; j < numConstants; j++) { var constant = matAnim.Constants[constantIndex + j]; float value = constant.Value; //A bit hacky, convert int32 types by value range SRT modes use if (constant.Value.Int32 > 0 && constant.Value.Int32 < 6) { value = constant.Value.Int32; } paramGroup.Tracks.Add(new ParamTrack() { Name = constant.AnimDataOffset.ToString("X"), ValueOffset = constant.AnimDataOffset, //Not the best way, but 4 is typically the stride size for each value ChannelIndex = (int)(constant.AnimDataOffset / 4), KeyFrames = new List <STKeyFrame>() { new STKeyFrame(0, value) }, InterpolationType = STInterpoaltionType.Constant, }); } //Loop through all int and float curve values for (int j = 0; j < numInts + numFloats; j++) { var curve = matAnim.Curves[curveIndex + j]; var paramTrack = new ParamTrack() { Name = curve.AnimDataOffset.ToString("X") }; paramTrack.ValueOffset = curve.AnimDataOffset; //Not the best way, but 4 is typically the stride size for each value paramTrack.ChannelIndex = (int)(curve.AnimDataOffset / 4); paramGroup.Tracks.Add(paramTrack); BfresAnimations.GenerateKeys(paramTrack, curve); } } } }
private void ParseParamTrack(FMAT material, STAnimGroup group, ParamTrack track) { if (!material.ShaderParams.ContainsKey(group.Name)) { return; } var value = track.GetFrameValue(this.Frame); //4 bytes per float or int value uint index = track.ValueOffset / 4; var targetParam = material.ShaderParams[group.Name]; var param = new ShaderParam(); if (!material.AnimatedParams.ContainsKey(group.Name)) { if (targetParam.DataValue is float[]) { float[] values = (float[])targetParam.DataValue; float[] dest = new float[values.Length]; Array.Copy(values, dest, values.Length); param.DataValue = dest; } else { param.DataValue = targetParam.DataValue; } param.Type = targetParam.Type; param.Name = group.Name; material.AnimatedParams.Add(group.Name, param); } param = material.AnimatedParams[group.Name]; switch (targetParam.Type) { case ShaderParamType.Float: param.DataValue = (float)value; break; case ShaderParamType.Float2: case ShaderParamType.Float3: case ShaderParamType.Float4: ((float[])param.DataValue)[index] = value; break; case ShaderParamType.Int: param.DataValue = value; break; case ShaderParamType.Int2: case ShaderParamType.Int3: case ShaderParamType.Int4: ((int[])param.DataValue)[index] = (int)value; break; case ShaderParamType.TexSrt: case ShaderParamType.TexSrtEx: { TexSrtMode mode = ((TexSrt)param.DataValue).Mode; var translateX = ((TexSrt)param.DataValue).Translation.X; var translateY = ((TexSrt)param.DataValue).Translation.Y; var rotate = ((TexSrt)param.DataValue).Rotation; var scaleX = ((TexSrt)param.DataValue).Scaling.X; var scaleY = ((TexSrt)param.DataValue).Scaling.Y; // if (track.ValueOffset == 0) mode = (TexSrtMode)Convert.ToUInt32(value); if (track.ValueOffset == 4) { scaleX = value; } if (track.ValueOffset == 8) { scaleY = value; } if (track.ValueOffset == 12) { rotate = value; } if (track.ValueOffset == 16) { translateX = value; } if (track.ValueOffset == 20) { translateY = value; } param.DataValue = new TexSrt() { Mode = mode, Scaling = new Syroot.Maths.Vector2F(scaleX, scaleY), Translation = new Syroot.Maths.Vector2F(translateX, translateY), Rotation = rotate, }; } break; case ShaderParamType.Srt2D: { var translateX = ((Srt2D)param.DataValue).Translation.X; var translateY = ((Srt2D)param.DataValue).Translation.Y; var rotate = ((Srt2D)param.DataValue).Rotation; var scaleX = ((Srt2D)param.DataValue).Scaling.X; var scaleY = ((Srt2D)param.DataValue).Scaling.Y; if (track.ValueOffset == 0) { scaleX = value; } if (track.ValueOffset == 4) { scaleY = value; } if (track.ValueOffset == 8) { rotate = value; } if (track.ValueOffset == 12) { translateX = value; } if (track.ValueOffset == 16) { translateY = value; } param.DataValue = new Srt2D() { Scaling = new Syroot.Maths.Vector2F(scaleX, scaleY), Translation = new Syroot.Maths.Vector2F(translateX, translateY), Rotation = rotate, }; } break; } }