This repository has been archived on 2024-11-03. You can view files and clone it, but cannot push or open issues or pull requests.
snakeinabox/Assets/Scripts/Render/GraphX.cs
2020-12-06 23:47:43 -08:00

164 lines
No EOL
4.5 KiB
C#

using System.Collections.Generic;
using System.Collections;
using UnityEngine;
public class GraphX
{
public GraphX(GraphXData data)
{
this.data = data;
}
GraphXData data;
Vector3 spinOffset;
Quaternion spin = Quaternion.identity;
Matrix4x4[] bodyMatrices = new Matrix4x4[9 * 7 * 9];
Matrix4x4[] coreMatrices = new Matrix4x4[3 * 3 * 3];
Matrix4x4 foodMatrix = new Matrix4x4();
Matrix4x4 tongueMatrix = new Matrix4x4();
Matrix4x4 arrowMatrix = new Matrix4x4();
Matrix4x4 faceMatrix = new Matrix4x4();
Matrix4x4 controllerMatrix = new Matrix4x4();
Matrix4x4 joystickMatrix = new Matrix4x4();
Matrix4x4 conArrowMatrix = new Matrix4x4();
public float foodScale = 0;
public float Exp(float value, int power)
{
for (int i = 0; i < power; i++)
{
value *= value;
}
return value;
}
public Quaternion GetNormalized(Quaternion q)
{
float f = 1f / Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
return new Quaternion(q.x * f, q.y * f, q.z * f, q.w * f);
}
public void Render(Main main)
{
Vector3 angleDelta = new Vector3(Exp(Mathf.Sin(Time.time * spinOffset.x), 3), Exp(Mathf.Sin(Time.time * spinOffset.y), 3), Exp(Mathf.Sin(Time.time * spinOffset.z), 3)) * Time.deltaTime * 180;
if (angleDelta.sqrMagnitude < 0.1)
{
spinOffset = new Vector3(
0.5f + Random.value,
0.5f + Random.value,
0.5f + Random.value
);
}
else
{
spin = Quaternion.Euler(angleDelta) * spin;
}
foodScale = Mathf.Lerp(foodScale, 1, 6 * Time.deltaTime);
foodMatrix.SetTRS(
main.food,
GetNormalized(spin),
foodScale * Vector3.one
); Graphics.DrawMesh(data.foodMesh, foodMatrix, data.snakeMat, 0);
if (main.playing && (data.faceMesh == data.faceDefault || data.faceEaten || data.faceHyper))
{
// tongueMatrix.SetTRS(
// main.snake[0],
// main.inputRot,
// Vector3.one
// ); Graphics.DrawMesh(data.tongueMesh, tongueMatrix, data.snakeMat, 0);
main.tongueLine.SetPosition(0, main.snake[0] + ((Vector3)main.dir * 0.4f));
Vector3 tip = main.snake[0] + main.inputRot * Vector3.forward * ((1 + Mathf.Clamp01(main.lerp * 3)) / 2);
float x = main.design.bounds.x + 0.5f;
float y = main.design.bounds.y + 0.5f;
float z = main.design.bounds.z + 0.5f;
tip.x = Mathf.Clamp(tip.x, -x, x);
tip.y = Mathf.Clamp(tip.y, -y, y);
tip.z = Mathf.Clamp(tip.z, -z, z);
main.tongueLine.SetPosition(1, tip);
}
else
{
main.tongueLine.SetPosition(0, Vector3.zero);
main.tongueLine.SetPosition(1, Vector3.zero);
}
if (!main.aiMode && main.playing)
{
arrowMatrix.SetTRS(
main.design.pivotPos + main.rig.head.rotation * Vector3.up * 2f,
main.inputRot,
Vector3.one
); Graphics.DrawMesh(data.arrowMesh, arrowMatrix, data.snakeMat, 9);
}
// Face
if (main.snake.Count > 0)
{
faceMatrix.SetTRS(
main.snake[0],
Quaternion.LookRotation(main.dir),
Vector3.one
); Graphics.DrawMesh(data.faceMesh, faceMatrix, data.snakeMat, 0);
// Body
for (int i = 1; i < bodyMatrices.Length; i++)
{
if (i > 0 && i < main.snake.Count)
{
Vector3 segmentDir = main.snake[i - 1] - main.snake[i];
if (segmentDir.sqrMagnitude == 0)
{
segmentDir = new Vector3Int(0, 0, 1);
}
bodyMatrices[i].SetTRS(main.snake[i], Quaternion.LookRotation(segmentDir), Vector3.one);
}
else
{
bodyMatrices[i].SetTRS(Vector3.zero, Quaternion.identity, Vector3.zero);
}
}
Graphics.DrawMeshInstanced(data.bodyMesh, 0, data.snakeMat, bodyMatrices);
}
// Core
for (int i = 0; i < coreMatrices.Length; i++)
{
if (i < main.core.Count)
{
coreMatrices[i].SetTRS(main.core[i], Quaternion.identity, Vector3.one);
}
else
{
coreMatrices[i].SetTRS(Vector3.zero, Quaternion.identity, Vector3.zero);
}
}
Graphics.DrawMeshInstanced(data.coreMesh, 0, data.snakeMat, coreMatrices);
// Body Roll
if (rollTime > 0)
{
rollTime -= Time.deltaTime;
}
else
{
if (main.justAte < 729)
{
Shader.SetGlobalInt("_JustAte", ++main.justAte);
}
rollTime = Mathf.Clamp01((60 / (float)main.bpm) / 27);
}
}
float rollTime;
public void Step(Main main)
{
Shader.SetGlobalInt("_JustAte", main.justAte++);
}
}