Add animation stub and effect stub for skin.

This commit is contained in:
2023-02-15 18:12:41 +08:00
parent b6e238780e
commit eb6dafbd60
6 changed files with 118 additions and 6 deletions

View File

@@ -0,0 +1,5 @@
namespace Cryville.Crtr.Components {
public class SkinAnimation : SkinComponent {
protected override void OnDestroy() { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 80318e36af5412345871bdbf80d49ef2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -18,6 +18,7 @@ namespace Cryville.Crtr {
public static void LoadDefault() {
if (loaded) return;
Components.Add("anim", typeof(SkinAnimation));
Components.Add("image", typeof(SpritePlane));
Components.Add("mesh", typeof(MeshBase));
Components.Add("polysec", typeof(PolygonSGO));

View File

@@ -43,6 +43,7 @@ namespace Cryville.Crtr {
buf[0] = _cb() ? (byte)1 : (byte)0;
}
}
public static readonly PropSrc Error = new Arbitrary(PdtInternalType.Error, new byte[0]);
public class Float : FixedBuffer {
readonly Func<float> _cb;
public Float(Func<float> cb) : base(PdtInternalType.Number, 4) { _cb = cb; }

View File

@@ -32,8 +32,28 @@ namespace Cryville.Crtr {
}
[Binder(typeof(PdtBinder))]
public class PdtSkin : SkinElement {
public Dictionary<Identifier, EffectDefinition> effects = new Dictionary<Identifier, EffectDefinition>();
public class PdtSkin {
public Dictionary<Identifier, AnimationSpan> animations
= new Dictionary<Identifier, AnimationSpan>();
public Dictionary<Identifier, EffectDefinition> effects
= new Dictionary<Identifier, EffectDefinition>();
public SkinElement elements;
public void Optimize(PdtEvaluator etor) {
foreach (var animation in animations.Values) {
animation.Optimize(etor);
}
foreach (var effect in effects.Values) {
etor.ContextCascadeInsert();
if (effect.args != null) foreach (var i in effect.args) {
etor.ContextCascadeUpdate(i.Key, PropSrc.Error);
}
etor.Optimize(effect.duration);
effect.elements.Optimize(etor);
etor.ContextCascadeDiscard();
}
elements.Optimize(etor);
}
}
public class SkinElement {
@@ -69,9 +89,25 @@ namespace Cryville.Crtr {
public class EffectDefinition {
public Identifier[] args;
public PdtExpression duration;
public SkinElement elements;
}
public class AnimationSpan {
[ElementList]
public Dictionary<SkinSelectors, SkinElement> elements
= new Dictionary<SkinSelectors, SkinElement>();
public Dictionary<Clip, AnimationSpan> spans
= new Dictionary<Clip, AnimationSpan>();
[PropertyList]
public Dictionary<SkinPropertyKey, PdtExpression> properties
= new Dictionary<SkinPropertyKey, PdtExpression>();
public void Optimize(PdtEvaluator etor) {
foreach (var p in properties.Values) {
etor.Optimize(p);
}
foreach (var e in spans.Values) {
e.Optimize(etor);
}
}
}
}

View File

@@ -13,9 +13,14 @@ namespace Cryville.Crtr {
readonly HashSet<string> a = new HashSet<string>();
readonly List<string> k = new List<string>(2);
protected override object InterpretKey(Type type) {
if (!typeof(SkinElement).IsAssignableFrom(type)) {
if (typeof(SkinElement).IsAssignableFrom(type))
return InterpretSkinElementKey();
else if (typeof(AnimationSpan).IsAssignableFrom(type))
return InterpretAnimationSpanKey();
else
return base.InterpretKey(type);
}
}
object InterpretSkinElementKey() {
s.Clear(); a.Clear(); k.Clear();
bool invalidKeyFlag = false, compKeyFlag = false;
while (true) {
@@ -103,6 +108,59 @@ namespace Cryville.Crtr {
if (Position == pp) throw new FormatException("Invalid selector or key format");
}
}
object InterpretAnimationSpanKey() {
if ((ct & 0x0040) != 0 || cc == ',') {
float start = 0, end = 1;
if (cc != ',') {
start = float.Parse(GetNumber());
ws(); if (cc != ',') throw new FormatException("Invalid span format");
}
GetChar(); ws();
if (cc != '{') end = float.Parse(GetNumber());
ws();
if (cc != '{') throw new FormatException("Invalid span format");
return new Clip(start, end);
}
k.Clear();
while (true) {
int pp = Position;
switch (cc) {
case '.':
GetChar();
if (k.Count != 1)
throw new FormatException("Invalid key format");
k.Add(GetIdentifier());
break;
case ';':
case ':':
switch (k.Count) {
case 1:
return new SkinPropertyKey.SetProperty {
Component = typeof(TransformInterface),
Name = IdentifierManager.SharedInstance.Request(k[0])
};
case 2:
return new SkinPropertyKey.SetProperty {
Component = GetComponentByName(k[0]),
Name = IdentifierManager.SharedInstance.Request(k[1])
};
default:
throw new FormatException("Unknown error"); // Unreachable
}
case '{':
throw new FormatException("Invalid token");
case '}':
throw new FormatException("Invalid token");
default:
if (k.Count != 0)
throw new FormatException("Invalid key format");
k.Add(GetIdentifier());
break;
}
ws();
if (Position == pp) throw new FormatException("Invalid selector or key format");
}
}
static Type GetComponentByName(string name) {
Type result;
if (GenericResources.Components.TryGetValue(name, out result)) return result;