Skip to content

Commit

Permalink
Merge pull request #329 from GothicVRProject/feature/zcvobanimate-v1
Browse files Browse the repository at this point in the history
Add initial implementation of zCVobAnimate
  • Loading branch information
JucanAndreiDaniel authored Mar 30, 2024
2 parents c793117 + 1491dc3 commit b2dab36
Show file tree
Hide file tree
Showing 16 changed files with 312 additions and 156 deletions.
60 changes: 60 additions & 0 deletions Assets/GothicVR/Resources/Prefabs/Vobs/zCVobAnimate.prefab
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &6503575194566409312
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2022050282646122291}
- component: {fileID: 5252305678164495226}
- component: {fileID: 8916690276963802196}
m_Layer: 0
m_Name: zCVobAnimate
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2022050282646122291
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6503575194566409312}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5252305678164495226
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6503575194566409312}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 024fa582612e45c0afcf4ba9d756341e, type: 3}
m_Name:
m_EditorClassIdentifier:
<visualScheme>k__BackingField:
--- !u!114 &8916690276963802196
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6503575194566409312}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 26c624505e9a4bf3a7b7e2fa4a9bd981, type: 3}
m_Name:
m_EditorClassIdentifier:

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion Assets/GothicVR/Scripts/Caches/AssetCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,15 @@ public static IMorphMesh TryGetMmb(string key)
if (MmbCache.TryGetValue(preparedKey, out var data))
return data;

var newData = new MorphMesh(GameData.Vfs, $"{preparedKey}.mmb").Cache();
IMorphMesh newData = null;
try
{
newData = new MorphMesh(GameData.Vfs, $"{preparedKey}.mmb").Cache();
}
catch (Exception)
{
// ignored
}
MmbCache[preparedKey] = newData;

return newData;
Expand Down
30 changes: 17 additions & 13 deletions Assets/GothicVR/Scripts/Caches/MorphMeshCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static class MorphMeshCache
/// | Array index is former vertexId
/// | Data is new vertexIds from Unity mesh
/// </summary>
private static readonly Dictionary<string, List<List<int>>> HeadVertexMapping = new();
private static readonly Dictionary<string, List<List<int>>> VertexMapping = new();

/// <summary>
/// We also store the vertices migrated from ZenKit to Unity. They basically differentiate by:
Expand All @@ -39,36 +39,40 @@ public static class MorphMeshCache
/// [0] - is frame ID of the Morph Animation
/// {{x,y,z}, {x,y,z}} - are the morph values of every vertex
/// </summary>
private static readonly Dictionary<string, List<Vector3[]>> HeadAnimationMorphs = new();
private static readonly Dictionary<string, List<Vector3[]>> AnimationMorphs = new();


public static bool IsMappingAlreadyCached(string morphMeshName)
{
var preparedKey = GetPreparedKey(morphMeshName);

return HeadVertexMapping.ContainsKey(preparedKey);
return VertexMapping.ContainsKey(preparedKey);
}

public static void AddVertexMapping(string morphMeshName, int arraySize)
{
var preparedKey = GetPreparedKey(morphMeshName);

HeadVertexMapping.Add(preparedKey, new(arraySize));
VertexMapping.Add(preparedKey, new(arraySize));

// Initialize
Enumerable.Range(0, arraySize)
.ToList()
.ForEach(_ => HeadVertexMapping[preparedKey].Add(new List<int>()));
.ForEach(_ => VertexMapping[preparedKey].Add(new List<int>()));
}

public static void AddVertexMappingEntry(string preparedMorphMeshName, int originalVertexIndex, int additionalUnityVertexIndex)
{
HeadVertexMapping[preparedMorphMeshName][originalVertexIndex].Add(additionalUnityVertexIndex);
var preparedKey = GetPreparedKey(preparedMorphMeshName);

VertexMapping[preparedKey][originalVertexIndex].Add(additionalUnityVertexIndex);
}

public static void SetUnityVerticesForVertexMapping(string preparedMorphMeshName, Vector3[] unityVertices)
{
UnityVertices.Add(preparedMorphMeshName, unityVertices);
var preparedKey = GetPreparedKey(preparedMorphMeshName);

UnityVertices.Add(preparedKey, unityVertices);
}

public static Vector3[] GetOriginalUnityVertices(string morphMeshName)
Expand All @@ -85,20 +89,20 @@ public static Vector3[] GetOriginalUnityVertices(string morphMeshName)
/// | Key is frameId
/// | Data is the already processed morph data (morph addition to original triangle data)
/// </summary>
public static List<Vector3[]> TryGetHeadMorphData(string mmbName, string animationName)
public static List<Vector3[]> TryGetMorphData(string mmbName, string animationName)
{
var preparedMmbKey = GetPreparedKey(mmbName);
var preparedAnimKey = GetPreparedKey(animationName);
var preparedKey = $"{preparedMmbKey}-{preparedAnimKey}";

if (HeadAnimationMorphs.TryGetValue(preparedKey, out var data))
if (AnimationMorphs.TryGetValue(preparedKey, out var data))
return data;

// Create logic
var mmb = AssetCache.TryGetMmb(mmbName);
var anim = mmb.Animations.First(anim => anim.Name.EqualsIgnoreCase(animationName));

var originalVertexMapping = HeadVertexMapping[preparedMmbKey];
var originalVertexMapping = VertexMapping[preparedMmbKey];
var originalUnityVertexData = UnityVertices[preparedMmbKey];
// Original vertex count from ZenKit data.
var vertexCount = anim.Vertices.Count;
Expand All @@ -124,7 +128,7 @@ public static List<Vector3[]> TryGetHeadMorphData(string mmbName, string animati
}
}

HeadAnimationMorphs[preparedKey] = newData;
AnimationMorphs[preparedKey] = newData;

return newData;
}
Expand All @@ -142,9 +146,9 @@ public static string GetPreparedKey(string key)

public static void Dispose()
{
HeadVertexMapping.Clear();
VertexMapping.Clear();
UnityVertices.Clear();
HeadAnimationMorphs.Clear();
AnimationMorphs.Clear();
}
}
}
2 changes: 2 additions & 0 deletions Assets/GothicVR/Scripts/Caches/PrefabCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum PrefabType
Npc,
WayPoint,
Vob,
VobAnimate,
VobItem,
VobContainer,
VobDoor,
Expand All @@ -34,6 +35,7 @@ private static string GetPath(PrefabType type)
PrefabType.Npc => "Prefabs/Npc",
PrefabType.WayPoint => "Prefabs/WayPoint",
PrefabType.Vob => "Prefabs/Vobs/Vob",
PrefabType.VobAnimate => "Prefabs/Vobs/zCVobAnimate",
PrefabType.VobItem => "Prefabs/Vobs/oCItem",
PrefabType.VobContainer => "Prefabs/Vobs/oCMobContainer",
PrefabType.VobDoor => "Prefabs/Vobs/oCMobDoor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public abstract class AbstractMeshBuilder

protected Vector3 RootPosition;
protected Quaternion RootRotation;

protected bool isMorphMeshMappingAlreadyCached;


public abstract GameObject Build();
Expand Down Expand Up @@ -102,6 +104,11 @@ public void SetMrm(IMultiResolutionMesh mrm)
this.Mrm = mrm;
}

public void SetMmb(IMorphMesh mmb)
{
this.Mmb = mmb;
}

public void SetMrm(string mrmName)
{
Mrm = AssetCache.TryGetMrm(mrmName);
Expand Down Expand Up @@ -268,6 +275,19 @@ protected GameObject BuildViaMdmAndMdh()
return RootGo;
}

protected GameObject BuildViaMmb()
{
var meshFilter = RootGo.AddComponent<MeshFilter>();
var meshRenderer = RootGo.AddComponent<MeshRenderer>();

PrepareMeshFilter(meshFilter, Mmb.Mesh, meshRenderer);
PrepareMeshRenderer(meshRenderer, Mmb.Mesh);

SetPosAndRot(RootGo, RootPosition, RootRotation);

return RootGo;
}

protected void PrepareMeshRenderer(Renderer rend, IMultiResolutionMesh mrmData)
{
if (null == mrmData)
Expand Down Expand Up @@ -317,7 +337,7 @@ protected void PrepareMeshRenderer(Renderer rend, IMultiResolutionMesh mrmData)
rend.SetMaterials(finalMaterials);
}

protected void PrepareMeshFilter(MeshFilter meshFilter, IMultiResolutionMesh mrmData, MeshRenderer meshRenderer, bool isMorphMesh = false, string morphMeshName = "")
protected void PrepareMeshFilter(MeshFilter meshFilter, IMultiResolutionMesh mrmData, MeshRenderer meshRenderer)
{
Mesh mesh = new Mesh();
meshFilter.mesh = mesh;
Expand Down Expand Up @@ -558,19 +578,44 @@ protected void PrepareMeshCollider(GameObject obj, Mesh mesh, List<IMaterial> ma
}
}

protected virtual void CreateMorphMeshBegin(IMultiResolutionMesh mrm, Mesh mesh)
private void CreateMorphMeshBegin(IMultiResolutionMesh mrm, Mesh mesh)
{
// NOP
if (Mmb == null)
{
return;
}

// MorphMeshes will change the vertices. This call optimizes performance.
mesh.MarkDynamic();

isMorphMeshMappingAlreadyCached = MorphMeshCache.IsMappingAlreadyCached(Mmb.Name);
if (isMorphMeshMappingAlreadyCached)
{
return;
}

MorphMeshCache.AddVertexMapping(Mmb.Name, mrm.PositionCount);
}

protected virtual void CreateMorphMeshEntry(int index1, int preparedVerticesCount)
private void CreateMorphMeshEntry(int index1, int preparedVerticesCount)
{
// NOP
// We add mapping data to later reuse for IMorphAnimation samples
if (Mmb == null || isMorphMeshMappingAlreadyCached)
{
return;
}

MorphMeshCache.AddVertexMappingEntry(Mmb.Name, index1, preparedVerticesCount - 1);
}

protected virtual void CreateMorphMeshEnd(List<Vector3> preparedVertices)
private void CreateMorphMeshEnd(List<Vector3> preparedVertices)
{
// NOP
if (Mmb == null || isMorphMeshMappingAlreadyCached)
{
return;
}

MorphMeshCache.SetUnityVerticesForVertexMapping(Mmb.Name, preparedVertices.ToArray());
}

/// <summary>
Expand Down
Loading

0 comments on commit b2dab36

Please sign in to comment.