Browse Source

Reworked brush game object creation so that entity brush models are configured differently from world brush models. Rearranged the VisualStyle class to fit this strategy.

readme
Nico de Poel 5 years ago
parent
commit
8fc85d5ecb
  1. 2
      Assets/Scripts/Game/Entity.cs
  2. 50
      Assets/Scripts/Game/GameState.cs
  3. 40
      Assets/Scripts/VisualStyle.cs

2
Assets/Scripts/Game/Entity.cs

@ -151,7 +151,7 @@ public class Entity
private void AssignMeshRenderer() private void AssignMeshRenderer()
{ {
material = visualStyle.CreateEntityMaterial();
material = visualStyle.CreateEntityMaterial(true);
if (aliasModel.IsAnimated) if (aliasModel.IsAnimated)
{ {

50
Assets/Scripts/Game/GameState.cs

@ -31,11 +31,11 @@ public class GameState
// The first sub-model contains all of the static geometry // The first sub-model contains all of the static geometry
var subModel = worldModel.GetSubModel(0); var subModel = worldModel.GetSubModel(0);
var subModelGO = CreateBrushGameObject(subModel);
var subModelGO = CreateWorldBrushObject(subModel);
subModelGO.transform.SetParent(worldGameObject.transform); subModelGO.transform.SetParent(worldGameObject.transform);
} }
private GameObject CreateBrushGameObject(BrushModel.SubModel subModel)
private GameObject CreateWorldBrushObject(BrushModel.SubModel subModel)
{ {
var subModelGO = new GameObject(subModel.Name) { layer = (int)uq.GameLayer }; var subModelGO = new GameObject(subModel.Name) { layer = (int)uq.GameLayer };
@ -44,13 +44,12 @@ public class GameState
var meshGO = new GameObject(surfaceMesh.Mesh.name) { layer = (int)uq.GameLayer }; var meshGO = new GameObject(surfaceMesh.Mesh.name) { layer = (int)uq.GameLayer };
meshGO.transform.SetParent(subModelGO.transform); meshGO.transform.SetParent(subModelGO.transform);
var mf = meshGO.AddComponent<MeshFilter>();
var mr = meshGO.AddComponent<MeshRenderer>();
mf.sharedMesh = surfaceMesh.Mesh;
var meshFilter = meshGO.AddComponent<MeshFilter>();
meshFilter.sharedMesh = surfaceMesh.Mesh;
// TODO FIXME This is wrong for brush model entities
uq.CurrentStyle.SetupWorldRenderer(mr);
mr.material = uq.CurrentStyle.CreateWorldMaterial(surfaceMesh.Flags); // TODO FIXME this currently leaks Materials
var meshRenderer = meshGO.AddComponent<MeshRenderer>();
uq.CurrentStyle.SetupWorldRenderer(meshRenderer);
meshRenderer.material = uq.CurrentStyle.CreateWorldMaterial(surfaceMesh.Flags); // TODO FIXME this currently leaks Materials
uint texNum = surfaceMesh.TextureNum; uint texNum = surfaceMesh.TextureNum;
if (uq.GameAssets.TryGetTexture(texNum, out var texture)) if (uq.GameAssets.TryGetTexture(texNum, out var texture))
@ -59,7 +58,36 @@ public class GameState
uq.GameAssets.TryGetTexture(fbNum, out var fullBright); uq.GameAssets.TryGetTexture(fbNum, out var fullBright);
uq.GameAssets.TryGetLightmap(surfaceMesh.Lightmap, out var lightmap); uq.GameAssets.TryGetLightmap(surfaceMesh.Lightmap, out var lightmap);
uq.CurrentStyle.SetWorldTextures(mr.material, texture, fullBright, lightmap);
uq.CurrentStyle.SetWorldTextures(meshRenderer.material, texture, fullBright, lightmap);
}
}
return subModelGO;
}
private GameObject CreateEntityBrushObject(BrushModel.SubModel subModel)
{
var subModelGO = new GameObject(subModel.Name) { layer = (int)uq.GameLayer };
foreach (var surfaceMesh in subModel.SurfaceMeshes)
{
var meshGO = new GameObject(surfaceMesh.Mesh.name) { layer = (int)uq.GameLayer };
meshGO.transform.SetParent(subModelGO.transform);
var meshFilter = meshGO.AddComponent<MeshFilter>();
meshFilter.sharedMesh = surfaceMesh.Mesh;
var meshRenderer = meshGO.AddComponent<MeshRenderer>();
uq.CurrentStyle.SetupEntityRenderer(meshRenderer);
meshRenderer.material = uq.CurrentStyle.CreateEntityMaterial(false); // TODO FIXME this currently leaks Materials
uint texNum = surfaceMesh.TextureNum;
if (uq.GameAssets.TryGetTexture(texNum, out var texture))
{
uint fbNum = surfaceMesh.FullBrightNum;
uq.GameAssets.TryGetTexture(fbNum, out var fullBright);
uq.CurrentStyle.SetEntityTextures(meshRenderer.material, texture, fullBright);
} }
} }
@ -112,7 +140,7 @@ public class GameState
var brushModelGO = new GameObject(brushModel.Name) { layer = (int)Layers.Game1 }; var brushModelGO = new GameObject(brushModel.Name) { layer = (int)Layers.Game1 };
for (int i = 0; i < brushModel.SubModelCount; ++i) for (int i = 0; i < brushModel.SubModelCount; ++i)
{ {
var subModelGO = CreateBrushGameObject(brushModel.GetSubModel(i));
var subModelGO = CreateEntityBrushObject(brushModel.GetSubModel(i));
subModelGO.transform.SetParent(brushModelGO.transform); subModelGO.transform.SetParent(brushModelGO.transform);
} }
@ -132,7 +160,7 @@ public class GameState
// TODO: these relatively complex world game objects are going to get destroyed and re-created all the time // TODO: these relatively complex world game objects are going to get destroyed and re-created all the time
// as the player moves through the map and moves in and out of range of these entities. This can and should // as the player moves through the map and moves in and out of range of these entities. This can and should
// be done more efficiently by creating the game objects only once and enabling/disabling them on demand. // be done more efficiently by creating the game objects only once and enabling/disabling them on demand.
var worldModelGO = CreateBrushGameObject(subModel);
var worldModelGO = CreateWorldBrushObject(subModel);
entity.SetWorldModel(worldModelGO); entity.SetWorldModel(worldModelGO);
} }

40
Assets/Scripts/VisualStyle.cs

@ -36,13 +36,22 @@ public class VisualStyle : ScriptableObject
Shader.DisableKeyword("_POINT_SAMPLING"); Shader.DisableKeyword("_POINT_SAMPLING");
} }
public virtual Material CreateEntityMaterial()
public virtual Material CreateEntityMaterial(bool aliasModel)
{ {
return new Material(entityMaterial);
var material = new Material(entityMaterial);
if (aliasModel && affineTexturing)
material.EnableKeyword("_AFFINE_ON");
else
material.DisableKeyword("_AFFINE_ON");
return material;
} }
public virtual Material CreateWorldMaterial(QSurfaceFlags surfaceFlags) public virtual Material CreateWorldMaterial(QSurfaceFlags surfaceFlags)
{ {
Material material;
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTurbulence) && liquidMaterial != null) if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTurbulence) && liquidMaterial != null)
{ {
float alpha = 1f; float alpha = 1f;
@ -55,14 +64,20 @@ public class VisualStyle : ScriptableObject
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTeleporter)) else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTeleporter))
alpha = liquidProperties.teleAlpha; alpha = liquidProperties.teleAlpha;
var material = new Material(liquidMaterial);
material = new Material(liquidMaterial);
material.SetColor("_BaseColor", new Color(1, 1, 1, alpha)); material.SetColor("_BaseColor", new Color(1, 1, 1, alpha));
return material;
}
else
{
material = new Material(worldMaterial);
} }
// TODO: enable alpha test for DrawFence flag
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawFence))
{
material.EnableKeyword("_ALPHATEST_ON");
}
return new Material(worldMaterial);
return material;
} }
public virtual void SetupEntityRenderer(MeshRenderer meshRenderer) public virtual void SetupEntityRenderer(MeshRenderer meshRenderer)
@ -100,11 +115,6 @@ public class VisualStyle : ScriptableObject
material.EnableKeyword("_EMISSION"); material.EnableKeyword("_EMISSION");
else else
material.DisableKeyword("_EMISSION"); material.DisableKeyword("_EMISSION");
if (affineTexturing)
material.EnableKeyword("_AFFINE_ON");
else
material.DisableKeyword("_AFFINE_ON");
} }
public virtual void SetWorldTextures(Material material, Texture2D mainTexture, Texture2D fullBright, Texture2D lightmap) public virtual void SetWorldTextures(Material material, Texture2D mainTexture, Texture2D fullBright, Texture2D lightmap)
@ -119,19 +129,15 @@ public class VisualStyle : ScriptableObject
else else
material.DisableKeyword("_EMISSION"); material.DisableKeyword("_EMISSION");
if (lightmap != null)
{
material.SetTexture("_LightMap", lightmap); material.SetTexture("_LightMap", lightmap);
if (lightmap != null)
material.EnableKeyword("_QLIGHTMAP_ON"); material.EnableKeyword("_QLIGHTMAP_ON");
}
else else
{
material.DisableKeyword("_QLIGHTMAP_ON"); material.DisableKeyword("_QLIGHTMAP_ON");
} }
}
} }
// TODO: should probably just use the cvars for this (r_wateralpha and such)
[System.Serializable] [System.Serializable]
public class LiquidProperties public class LiquidProperties
{ {

Loading…
Cancel
Save