117 lines
No EOL
2.3 KiB
C#
117 lines
No EOL
2.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
public class Vhysics
|
|
{
|
|
Monolith mono;
|
|
|
|
public void Start(Monolith mono)
|
|
{
|
|
this.mono = mono;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
// bounds
|
|
VoxelCollision(mono.player);
|
|
VoxelCollision(mono.pump);
|
|
|
|
for (int i = 0; i < mono.bats.Length; i++)
|
|
{
|
|
VoxelObject bat = mono.bats[i];
|
|
if (bat.active)
|
|
{
|
|
VoxelCollision(bat);
|
|
}
|
|
}
|
|
|
|
// FAT
|
|
// hit callbacks
|
|
// rectangular bounds
|
|
// larger than one voxel
|
|
}
|
|
|
|
public void VoxelCollision(VoxelObject vobj)
|
|
{
|
|
Vector3 toPos = vobj.pos + vobj.voxelBody.velocity * Time.deltaTime;
|
|
|
|
int w = 0;
|
|
while (w < 3)
|
|
{
|
|
Vector3 clampPos = new Vector3(
|
|
Mathf.Clamp(toPos.x, Bound(vobj, 0, -1), Bound(vobj, 0, 1)),
|
|
Mathf.Clamp(toPos.y, Bound(vobj, 1, -1), Bound(vobj, 1, 1)),
|
|
Mathf.Clamp(toPos.z, Bound(vobj, 2, -1), Bound(vobj, 2, 1))
|
|
);
|
|
|
|
float largest = 0;
|
|
int largeIndex = -1;
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
float dist = Mathf.Abs(toPos[j] - clampPos[j]);
|
|
if (dist > largest)
|
|
{
|
|
largeIndex = j;
|
|
largest = dist;
|
|
}
|
|
}
|
|
|
|
if (largeIndex > -1)
|
|
{
|
|
toPos[largeIndex] = clampPos[largeIndex];
|
|
vobj.voxelBody.velocity[largeIndex] *= -0.25f; // Bounce
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
|
|
w++;
|
|
}
|
|
|
|
vobj.pos = toPos;
|
|
}
|
|
|
|
public float Bound(VoxelObject vobj, int axis, int dir)
|
|
{
|
|
Vector3Int step = Vector3Int.zero;
|
|
step[axis] = dir;
|
|
|
|
float bound = Mathf.Infinity * dir;
|
|
float closest = Mathf.Infinity;
|
|
for (int i = 0; i < mono.allDirs.Length; i++)
|
|
{
|
|
Vector3 d = (Vector3)mono.allDirs[i] * (vobj.voxelBody.boundRadius - 0.001f);
|
|
d[axis] = 0;
|
|
Vector3 vPos = Voxelcast(mono.VoxelPos(vobj.pos + d), step);
|
|
float dist = Mathf.Abs(vPos[axis] - vobj.pos[axis]);
|
|
if (dist < closest)
|
|
{
|
|
bound = vPos[axis];
|
|
closest = dist;
|
|
}
|
|
}
|
|
// when hit ?
|
|
return bound + (((1 - vobj.voxelBody.boundRadius * 2) / 2) * dir);
|
|
}
|
|
|
|
public Vector3Int Voxelcast(Vector3Int from, Vector3Int step)
|
|
{
|
|
Vector3Int vPos = from;
|
|
int i = 0;
|
|
while (i < 15)
|
|
{
|
|
vPos += step;
|
|
if (!mono.InVoxel(vPos))
|
|
{
|
|
vPos -= step;
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return vPos;
|
|
}
|
|
} |