Experimental UV animations playing from YCD. (some air cons broken!)

This commit is contained in:
dexy 2019-11-02 06:46:45 +11:00
parent fe4ff6300e
commit 80b6f3742b
29 changed files with 212 additions and 39 deletions

View File

@ -503,7 +503,9 @@ namespace CodeWalker.GameFiles
public override float EvaluateFloat(int frame)
{
return Values[Frames[frame]];
if(frame<Frames?.Length) return Values[Frames[frame]];
if (Values?.Length > 0) return Values[0];
return Offset;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class AnimChannelQuantizeFloat : AnimChannel
@ -531,7 +533,9 @@ namespace CodeWalker.GameFiles
public override float EvaluateFloat(int frame)
{
return Values[frame];
if (frame < Values?.Length) return Values[frame];
if (Values?.Length > 0) return Values[0];
return Offset;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class AnimChannelLinearFloat : AnimChannel
@ -640,7 +644,9 @@ namespace CodeWalker.GameFiles
public override float EvaluateFloat(int frame)
{
return Values[frame];
if (frame < Values?.Length) return Values[frame];
if (Values?.Length > 0) return Values[0];
return Offset;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class AnimChannelType7 : AnimChannel
@ -737,6 +743,46 @@ namespace CodeWalker.GameFiles
return Quaternion.Identity;
}
}
public Vector4 EvaluateVector(int frame)
{
if (Channels == null) return Vector4.Zero;
var v = Vector4.Zero;
int c = 0;
for (int i = 0; i < Channels.Length; i++)
{
if (c >= 4) break;
var channel = Channels[i];
var sv3c = channel as AnimChannelStaticVector3;
var ssqc = channel as AnimChannelStaticSmallestThreeQuaternion;
if (sv3c != null)
{
for (int n = 0; n < 3; n++)
{
if ((c + n) >= 4) break;
v[c + n] = sv3c.Value[n];
}
c += 3;
}
else if (ssqc != null)
{
for (int n = 0; n < 4; n++)
{
if ((c + n) >= 4) break;
v[c + n] = sv3c.Value[n];
}
c += 4;
}
else
{
v[c] = channel.EvaluateFloat(frame);
c++;
}
}
return v;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class Sequence : ResourceSystemBlock
{

View File

@ -71,6 +71,14 @@ namespace CodeWalker.Rendering
public bool HasSkeleton;
public bool HasTransforms;
public bool HasAnims = false;
public double CurrentAnimTime = 0;
public YcdFile ClipDict;
public ClipMapEntry ClipMapEntry;
public ClipMapEntry ClipMapEntryUV0;
public ClipMapEntry ClipMapEntryUV1;
public override void Init(DrawableBase drawable)
{
@ -119,7 +127,7 @@ namespace CodeWalker.Rendering
VlowModels = new RenderableModel[vlow.Length];
for (int i = 0; i < vlow.Length; i++)
{
VlowModels[i] = InitModel(vlow[i]);
VlowModels[i] = InitModel(vlow[i]);
AllModels[curmodel + i] = VlowModels[i];
}
curmodel += vlow.Length;
@ -330,6 +338,106 @@ namespace CodeWalker.Rendering
return Key.ToString();
}
public void UpdateAnims(double realTime)
{
if (CurrentAnimTime == realTime) return;//already updated this!
CurrentAnimTime = realTime;
if (ClipMapEntry != null)
{
UpdateAnim(ClipMapEntry); //animate skeleton/models here
}
if (ClipMapEntryUV0 != null)
{
UpdateAnimUV(ClipMapEntryUV0); //animate UVs
}
if (ClipMapEntryUV1 != null)
{
UpdateAnimUV(ClipMapEntryUV1); //animate UVs
}
}
private void UpdateAnim(ClipMapEntry cme)
{
var clipanim = cme.Clip as ClipAnimation;//maybe ClipAnimationList?
var anim = clipanim?.Animation;
if (anim == null)
{ return; }
//TODO........
}
private void UpdateAnimUV(ClipMapEntry cme)
{
if (cme.Next != null) //is this a "chain" of clips to play..?
{
//cme = cme.Next;
}
var clipanim = cme.Clip as ClipAnimation;//maybe ClipAnimationList?
var anim = clipanim?.Animation;
if (anim == null)
{ return; }
if (anim.BoneIds?.data_items == null)
{ return; }
if (anim.Sequences?.data_items == null)
{ return; }
bool interpolate = true; //how to know? eg. cs4_14_hickbar_anim shouldn't
bool lastFrameSameAsFirst = true;//if last frame is equivalent to the first one, eg rollercoaster small light "globes" don't
var duration = anim.Duration;
var frames = anim.Frames;
var nframes = (lastFrameSameAsFirst) ? (frames - 1) : frames;
var curPos = ((CurrentAnimTime % duration) / duration) * nframes;
var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1) % frames;
var falpha = (float)(curPos - Math.Floor(curPos));
var ialpha = 1.0f - falpha;
var globalAnimUV0 = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
var globalAnimUV1 = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
for (int i = 0; i < anim.BoneIds.data_items.Length; i++)
{
var boneiditem = anim.BoneIds.data_items[i];
var track = boneiditem.Track;
if ((track != 17) && (track != 18))
{ continue; }//17 and 18 would be UV0 and UV1
for (int s = 0; s < anim.Sequences.data_items.Length; s++)
{
var seq = anim.Sequences.data_items[s];
var aseq = seq.Sequences[i];
var v0 = aseq.EvaluateVector(frame0);
var v1 = aseq.EvaluateVector(frame1);
var v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
switch (track)
{
case 17: globalAnimUV0 = v; break; //could be overwriting values here...
case 18: globalAnimUV1 = v; break;
}
}
}
foreach (var model in HDModels) //TODO: figure out which models/geometries this should be applying to!
{
if (model == null) continue;
foreach (var geom in model.Geometries)
{
if (geom == null) continue;
if (geom.globalAnimUVEnable)
{
geom.globalAnimUV0 = globalAnimUV0;
geom.globalAnimUV1 = globalAnimUV1;
}
}
}
}
}
public class RenderableModel
@ -424,8 +532,8 @@ namespace CodeWalker.Rendering
public float RippleBumpiness { get; set; } = 1.0f;
public Vector4 WindGlobalParams { get; set; } = Vector4.Zero;
public Vector4 WindOverrideParams { get; set; } = Vector4.One;
public Vector4 globalAnimUV0 { get; set; } = Vector4.Zero;
public Vector4 globalAnimUV1 { get; set; } = Vector4.Zero;
public Vector4 globalAnimUV0 { get; set; } = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
public Vector4 globalAnimUV1 { get; set; } = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
public Vector4 DirtDecalMask { get; set; } = Vector4.Zero;
public bool SpecOnly { get; set; } = false;
public float WaveOffset { get; set; } = 0; //for terrainfoam
@ -433,6 +541,7 @@ namespace CodeWalker.Rendering
public float WaveMovement { get; set; } = 0; //for terrainfoam
public float HeightOpacity { get; set; } = 0; //for terrainfoam
public bool HDTextureEnable = true;
public bool globalAnimUVEnable = false;
public static ShaderParamNames[] GetTextureSamplerList()
@ -612,9 +721,11 @@ namespace CodeWalker.Rendering
break;
case ShaderParamNames.globalAnimUV0:
globalAnimUV0 = (Vector4)param.Data;
globalAnimUVEnable = true;
break;
case ShaderParamNames.globalAnimUV1:
globalAnimUV1 = (Vector4)param.Data;
globalAnimUVEnable = true;
break;
case ShaderParamNames.WaveOffset:
WaveOffset = ((Vector4)param.Data).X;

View File

@ -2534,6 +2534,13 @@ namespace CodeWalker.Rendering
if (rndbl.HasAnims)
{
rndbl.UpdateAnims(currentRealTime);
}
if ((rendercollisionmeshes || (SelectionMode == MapSelectionMode.Collision)) && rendercollisionmeshlayerdrawable)
{
Drawable sdrawable = rndbl.Key as Drawable;
@ -2779,31 +2786,18 @@ namespace CodeWalker.Rendering
Renderable rndbl = renderableCache.GetRenderable(drawable);
if (rndbl == null) return null;
if (clipDict != 0)
if ((clipDict != 0) && (rndbl.ClipDict == null))
{
YcdFile ycd = gameFileCache.GetYcd(clipDict);
if ((ycd != null) && (ycd.Loaded))
{
rndbl.ClipDict = ycd;
MetaHash ahash = arche.Hash;
MetaHash ahashuv1 = ahash + 1;
MetaHash ahashuv2 = ahash + 2;
ClipMapEntry cme, cmeuv1, cmeuv2; //this goes to at least uv5! (from uv0) - see hw1_09.ycd
bool found = false;
if (ycd.ClipMap.TryGetValue(ahash, out cme))
{
found = true;
}
if (ycd.ClipMap.TryGetValue(ahashuv1, out cmeuv1))
{
found = true;
}
if (ycd.ClipMap.TryGetValue(ahashuv2, out cmeuv2))
{
found = true;
}
if (!found)
{
}
MetaHash ahashuv0 = ahash + 1; //this goes to at least uv5! (from uv0) - see hw1_09.ycd
MetaHash ahashuv1 = ahash + 2;
if (ycd.ClipMap.TryGetValue(ahash, out rndbl.ClipMapEntry)) rndbl.HasAnims = true;
if (ycd.ClipMap.TryGetValue(ahashuv0, out rndbl.ClipMapEntryUV0)) rndbl.HasAnims = true;
if (ycd.ClipMap.TryGetValue(ahashuv1, out rndbl.ClipMapEntryUV1)) rndbl.HasAnims = true;
}
}

View File

@ -43,6 +43,8 @@ namespace CodeWalker.Rendering
public uint IsDecal;
public uint EnableWind;
public Vector4 WindOverrideParams;
public Vector4 globalAnimUV0;
public Vector4 globalAnimUV1;
}
public struct BasicShaderPSSceneVars
{
@ -695,6 +697,8 @@ namespace CodeWalker.Rendering
VSGeomVars.Vars.IsDecal = DecalMode ? 1u : 0u;
VSGeomVars.Vars.EnableWind = windflag;
VSGeomVars.Vars.WindOverrideParams = geom.WindOverrideParams;
VSGeomVars.Vars.globalAnimUV0 = geom.globalAnimUV0;
VSGeomVars.Vars.globalAnimUV1 = geom.globalAnimUV1;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);
@ -811,6 +815,8 @@ namespace CodeWalker.Rendering
VSGeomVars.Vars.IsDecal = 0;
VSGeomVars.Vars.EnableWind = 0;
VSGeomVars.Vars.WindOverrideParams = Vector4.Zero;
VSGeomVars.Vars.globalAnimUV0 = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
VSGeomVars.Vars.globalAnimUV1 = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);

View File

@ -40,7 +40,10 @@ namespace CodeWalker.Rendering
public uint EnableTint;
public float TintYVal;
public uint IsDecal;
public uint Pad5;
public uint EnableWind;
public Vector4 WindOverrideParams;
public Vector4 globalAnimUV0;
public Vector4 globalAnimUV1;
}
public struct CableShaderPSSceneVars
{
@ -273,6 +276,10 @@ namespace CodeWalker.Rendering
VSGeomVars.Vars.EnableTint = 0u;
VSGeomVars.Vars.TintYVal = 0u;
VSGeomVars.Vars.IsDecal = 0u;
VSGeomVars.Vars.EnableWind = 0u;
VSGeomVars.Vars.WindOverrideParams = Vector4.Zero;
VSGeomVars.Vars.globalAnimUV0 = Vector4.Zero;
VSGeomVars.Vars.globalAnimUV1 = Vector4.Zero;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);

View File

@ -28,6 +28,8 @@ cbuffer VSGeomVars : register(b4)
uint IsDecal;
uint EnableWind;
float4 WindOverrideParams;
float4 globalAnimUV0;
float4 globalAnimUV1;
}
cbuffer VSInstGlobals : register(b5)
{
@ -312,7 +314,14 @@ float4 ColourTint(float tx, float tx2, uint iid)
float2 GlobalUVAnim(float2 uv)
{
float2 r;
float3 uvw = float3(uv, 1);
r.x = dot(globalAnimUV0.xyz, uvw);
r.y = dot(globalAnimUV1.xyz, uvw);
return r;
}

Binary file not shown.

View File

@ -28,7 +28,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = 0.5;// input.Texcoord;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -29,7 +29,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -30,7 +30,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = input.Texcoord2;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -31,7 +31,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = input.Texcoord2;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -30,7 +30,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -29,7 +29,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = 0.5;// input.Texcoord;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -27,7 +27,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = 0.5;// input.Texcoord;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -28,7 +28,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -30,7 +30,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = input.Texcoord2;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -29,7 +29,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = input.Texcoord1;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.

View File

@ -28,7 +28,7 @@ VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
output.Position = cpos;
output.CamRelPos = opos;
output.Normal = bnorm;
output.Texcoord0 = input.Texcoord0;
output.Texcoord0 = GlobalUVAnim(input.Texcoord0);
output.Texcoord1 = 0.5;// input.Texcoord;
output.Texcoord2 = 0.5;// input.Texcoord;
output.Colour0 = input.Colour0;

Binary file not shown.