Browse Source

Dynamically create either MeshRenderer/MeshFilter or SkinnedMeshRenderer based on whether the model being assigned is animated or not. Gets rid of warnings on un-animated SkinnedMeshRenderers, and removes unnecessary components on brush model entities.

console
Nico de Poel 5 years ago
parent
commit
c14faf2666
  1. 61
      Assets/Scripts/Game/Entity.cs
  2. 2
      Assets/Scripts/Modules/GameModule.cs
  3. 4
      Assets/Scripts/Modules/RenderModule.cs
  4. 15
      Assets/Scripts/Support/AliasModel.cs

61
Assets/Scripts/Game/Entity.cs

@ -6,7 +6,10 @@ public class Entity
private readonly int entityNum;
private GameObject gameObject;
private SkinnedMeshRenderer meshRenderer;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private SkinnedMeshRenderer skinnedMeshRenderer;
private AliasModel aliasModel;
private GameObject worldModel;
@ -20,14 +23,6 @@ public class Entity
private void CreateGameObject()
{
gameObject = new GameObject($"Entity_{entityNum}");
// DEBUG - we'll want to instantiate a prefab and assign materials from a preset collection
meshRenderer = gameObject.AddComponent<SkinnedMeshRenderer>();
meshRenderer.material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
meshRenderer.receiveShadows = false;
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
public void Destroy()
@ -38,12 +33,20 @@ public class Entity
public void ClearModel()
{
aliasModel = null;
meshRenderer.sharedMesh = null;
Object.Destroy(meshFilter);
Object.Destroy(meshRenderer);
Object.Destroy(skinnedMeshRenderer);
// TODO: not sure if this is the right way to unlink world sub-models
gameObject.transform.DetachChildren();
}
public void SetAliasModel(AliasModel model)
{
ClearModel();
aliasModel = model;
AssignMeshRenderer();
// Set a default pose based on the first animation frame
UpdateAnimation(0);
@ -51,6 +54,7 @@ public class Entity
public void SetWorldModel(GameObject worldModelGO)
{
ClearModel();
worldModel = worldModelGO;
worldModel.transform.SetParent(gameObject.transform);
}
@ -60,10 +64,17 @@ public class Entity
if (aliasModel != null)
{
aliasModel.Animate(frameNum, out Mesh mesh, out float blendWeight);
meshRenderer.sharedMesh = mesh;
if (skinnedMeshRenderer != null)
{
skinnedMeshRenderer.sharedMesh = mesh;
if (mesh != null && mesh.blendShapeCount > 0)
meshRenderer.SetBlendShapeWeight(0, blendWeight);
skinnedMeshRenderer.SetBlendShapeWeight(0, blendWeight);
}
else if (meshFilter != null)
{
meshFilter.sharedMesh = mesh;
}
}
if (worldModel != null)
@ -77,4 +88,30 @@ public class Entity
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
}
private void AssignMeshRenderer()
{
// DEBUG - we'll want to instantiate a prefab and assign materials from a preset collection
var material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
if (aliasModel.IsAnimated)
{
skinnedMeshRenderer = gameObject.AddComponent<SkinnedMeshRenderer>();
skinnedMeshRenderer.material = material;
skinnedMeshRenderer.shadowCastingMode = ShadowCastingMode.Off;
skinnedMeshRenderer.receiveShadows = false;
skinnedMeshRenderer.lightProbeUsage = LightProbeUsage.Off;
skinnedMeshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
else
{
meshFilter = gameObject.AddComponent<MeshFilter>();
meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.material = material;
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
meshRenderer.receiveShadows = false;
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
}
}

2
Assets/Scripts/Modules/GameModule.cs

@ -24,7 +24,7 @@ public partial class GameModule
{
if (!int.TryParse(modelName.Substring(1), out int subModelNum))
{
Debug.LogWarning($"Invalid world submodel index: {modelName}");
Debug.LogWarning($"Invalid world sub-model index: {modelName}");
return;
}

4
Assets/Scripts/Modules/RenderModule.cs

@ -31,8 +31,8 @@ public partial class RenderModule
Debug.Log($"Alias model '{name}' (frame type {frameType}) with {header.numVerts} vertices, {header.numTriangles} triangles, {header.numFrames} frame(s), {header.numPoses} pose(s):\n{sb}");
AliasModel aliasModel = new AliasModel(name, frameType);
aliasModel.ImportMeshData(header, poseVertices, triangles, stVertices);
AliasModel aliasModel = new AliasModel(name, header, frameType);
aliasModel.ImportMeshData(poseVertices, triangles, stVertices);
uq.GameAssets.AddAliasModel(aliasModel);

15
Assets/Scripts/Support/AliasModel.cs

@ -8,14 +8,17 @@ public class AliasModel
private static readonly Regex AnimationRegex = new Regex(@"^[a-zA-Z]+");
private readonly string name;
private readonly QAliasHeader header;
private readonly QAliasFrameType frameType;
private readonly List<(int, Mesh)> animationMeshes = new List<(int, Mesh)>();
public string Name => name;
public bool IsAnimated => header.numPoses > 1;
public AliasModel(string name, QAliasFrameType frameType)
public AliasModel(string name, QAliasHeader header, QAliasFrameType frameType)
{
this.name = name;
this.header = header;
this.frameType = frameType;
}
@ -72,7 +75,7 @@ public class AliasModel
animationMeshes.Clear();
}
public void ImportMeshData(QAliasHeader header, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices)
public void ImportMeshData(QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices)
{
// Massage the input data for easier conversion
PreprocessMeshData(header, triangles, ref poseVertices, ref stVertices);
@ -83,12 +86,12 @@ public class AliasModel
// Identify animation sequences and turn each one into a separate Mesh with a single blend shape animation
if (frameType == QAliasFrameType.Single)
ImportSingleFrameAnimations(header, poseVertices, indices, uvs);
ImportSingleFrameAnimations(poseVertices, indices, uvs);
else
ImportGroupFrameAnimations(header, poseVertices, indices, uvs);
ImportGroupFrameAnimations(poseVertices, indices, uvs);
}
private void ImportSingleFrameAnimations(QAliasHeader header, QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs)
private void ImportSingleFrameAnimations(QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs)
{
Mesh mesh;
string animName = null;
@ -119,7 +122,7 @@ public class AliasModel
animationMeshes.Add((startFrame, mesh));
}
private void ImportGroupFrameAnimations(QAliasHeader header, QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs)
private void ImportGroupFrameAnimations(QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs)
{
for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx)
{

Loading…
Cancel
Save