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. 65
      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

65
Assets/Scripts/Game/Entity.cs

@ -6,7 +6,10 @@ public class Entity
private readonly int entityNum; private readonly int entityNum;
private GameObject gameObject; private GameObject gameObject;
private SkinnedMeshRenderer meshRenderer;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private SkinnedMeshRenderer skinnedMeshRenderer;
private AliasModel aliasModel; private AliasModel aliasModel;
private GameObject worldModel; private GameObject worldModel;
@ -20,14 +23,6 @@ public class Entity
private void CreateGameObject() private void CreateGameObject()
{ {
gameObject = new GameObject($"Entity_{entityNum}"); 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() public void Destroy()
@ -38,12 +33,20 @@ public class Entity
public void ClearModel() public void ClearModel()
{ {
aliasModel = null; 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) public void SetAliasModel(AliasModel model)
{ {
ClearModel();
aliasModel = model; aliasModel = model;
AssignMeshRenderer();
// Set a default pose based on the first animation frame // Set a default pose based on the first animation frame
UpdateAnimation(0); UpdateAnimation(0);
@ -51,6 +54,7 @@ public class Entity
public void SetWorldModel(GameObject worldModelGO) public void SetWorldModel(GameObject worldModelGO)
{ {
ClearModel();
worldModel = worldModelGO; worldModel = worldModelGO;
worldModel.transform.SetParent(gameObject.transform); worldModel.transform.SetParent(gameObject.transform);
} }
@ -60,10 +64,17 @@ public class Entity
if (aliasModel != null) if (aliasModel != null)
{ {
aliasModel.Animate(frameNum, out Mesh mesh, out float blendWeight); aliasModel.Animate(frameNum, out Mesh mesh, out float blendWeight);
meshRenderer.sharedMesh = mesh;
if (mesh != null && mesh.blendShapeCount > 0)
meshRenderer.SetBlendShapeWeight(0, blendWeight);
if (skinnedMeshRenderer != null)
{
skinnedMeshRenderer.sharedMesh = mesh;
if (mesh != null && mesh.blendShapeCount > 0)
skinnedMeshRenderer.SetBlendShapeWeight(0, blendWeight);
}
else if (meshFilter != null)
{
meshFilter.sharedMesh = mesh;
}
} }
if (worldModel != null) if (worldModel != null)
@ -77,4 +88,30 @@ public class Entity
gameObject.transform.position = position; gameObject.transform.position = position;
gameObject.transform.rotation = rotation; 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)) 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; 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}"); 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); 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 static readonly Regex AnimationRegex = new Regex(@"^[a-zA-Z]+");
private readonly string name; private readonly string name;
private readonly QAliasHeader header;
private readonly QAliasFrameType frameType; private readonly QAliasFrameType frameType;
private readonly List<(int, Mesh)> animationMeshes = new List<(int, Mesh)>(); private readonly List<(int, Mesh)> animationMeshes = new List<(int, Mesh)>();
public string Name => name; 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.name = name;
this.header = header;
this.frameType = frameType; this.frameType = frameType;
} }
@ -72,7 +75,7 @@ public class AliasModel
animationMeshes.Clear(); 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 // Massage the input data for easier conversion
PreprocessMeshData(header, triangles, ref poseVertices, ref stVertices); 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 // Identify animation sequences and turn each one into a separate Mesh with a single blend shape animation
if (frameType == QAliasFrameType.Single) if (frameType == QAliasFrameType.Single)
ImportSingleFrameAnimations(header, poseVertices, indices, uvs);
ImportSingleFrameAnimations(poseVertices, indices, uvs);
else 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; Mesh mesh;
string animName = null; string animName = null;
@ -119,7 +122,7 @@ public class AliasModel
animationMeshes.Add((startFrame, mesh)); 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) for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx)
{ {

Loading…
Cancel
Save