using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; public partial class RenderModule { private readonly UniQuake uq; public RenderModule(UniQuake uniQuake) { uq = uniQuake; BuildCallbacks(); zPos = globalZPos; globalZPos -= 256f; } private float xPos = -2048f; private float zPos = 0f; private static float globalZPos = 0f; private int UploadAliasModel(string name, QAliasHeader header, QAliasFrameType frameType, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices, QGLTexture[][] glTextures, QGLTexture[][] fbTextures) { var sb = new System.Text.StringBuilder(); foreach (var frame in header.frames) { sb.AppendLine($"- {frame.name} ({frame.numPoses} poses)"); } 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, header, frameType); aliasModel.ImportMeshData(poseVertices, triangles, stVertices); uq.GameAssets.AddAliasModel(aliasModel); string modelName = System.IO.Path.GetFileNameWithoutExtension(name); var go = new GameObject(modelName); go.transform.SetPositionAndRotation(new Vector3(xPos, 0, zPos), Quaternion.identity); aliasModel.Animate(0, out Mesh mesh, out float blendWeight); var material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); uint texNum = glTextures[0][0].texNum; if (uq.GameAssets.TryGetTexture(texNum, out var texture)) { material.mainTexture = texture; } if (fbTextures != null && fbTextures[0] != null && fbTextures[0][0] != null) { var fbTexNum = fbTextures[0][0].texNum; if (uq.GameAssets.TryGetTexture(fbTexNum, out var fbTexture)) { material.EnableKeyword("_EMISSION"); material.SetTexture("_EmissionMap", fbTexture); material.SetColor("_EmissionColor", Color.white); } } if (header.numPoses > 1) { var mr = go.AddComponent(); mr.material = material; mr.sharedMesh = mesh; mr.shadowCastingMode = ShadowCastingMode.Off; mr.receiveShadows = false; mr.lightProbeUsage = LightProbeUsage.Off; mr.reflectionProbeUsage = ReflectionProbeUsage.Off; var animator = go.AddComponent(); animator.aliasModel = aliasModel; } else { var mf = go.AddComponent(); mf.sharedMesh = mesh; var mr = go.AddComponent(); mr.material = material; mr.shadowCastingMode = ShadowCastingMode.Off; mr.receiveShadows = false; mr.lightProbeUsage = LightProbeUsage.Off; mr.reflectionProbeUsage = ReflectionProbeUsage.Off; } xPos += 128f; return 1; } private int UploadBrushModel(QModel model) { Debug.Log($"Brush model '{model.name}' with {model.numVertices} vertices, {model.numEdges} edges, {model.numSurfaces} surfaces"); var brushModel = new BrushModel(model.name); brushModel.ImportMeshData(model); uq.GameAssets.AddBrushModel(brushModel); return 1; } private int UploadWorldModel(QModel model) { Debug.Log($"World model '{model.name}' with {model.numVertices} vertices, {model.numEdges} edges, {model.numSurfaces} surfaces"); var worldModel = new BrushModel(model.name); worldModel.ImportMeshData(model); uq.GameAssets.SetWorldModel(worldModel); uq.GameState.NewMap(worldModel); return 1; } private bool UploadTexture(QGLTexture texture, byte[] data, ref uint texNum) { Debug.Log($"Texture '{texture.name}' with dimensions {texture.width}x{texture.height}, data size = {data.Length} bytes"); if (texture.width == 0 || texture.height == 0) return false; var tex = new Texture2D((int)texture.width, (int)texture.height, TextureFormat.RGBA32, texture.flags.HasFlag(QTexPrefs.Mipmap)); tex.name = texture.name; tex.SetPixelData(data, 0); tex.Apply(); texNum = uq.GameAssets.SetTexture(texNum, tex); return true; } private void SetupView(QVec3 origin, QVec3 angles, QLeaf viewLeaf) { var cam = uq.Camera; if (cam == null) return; angles.y -= 90; // Don't know why this correction is necessary cam.transform.position = origin.ToUnityPosition(); cam.transform.rotation = angles.ToUnityRotation(); } }