Refactor voxel physics

This commit is contained in:
spatialfree 2020-09-25 05:57:09 -07:00
parent 642a863f1a
commit 5d67732bb8
9 changed files with 369 additions and 350 deletions

98
Assets/Bounds.mat Normal file
View file

@ -0,0 +1,98 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Bounds
m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _ALPHABLEND_ON
m_LightmapFlags: 0
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 3000
stringTagMap:
RenderType: Transparent
disabledShaderPasses:
- ALWAYS
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BlendOp: 0
- _BumpScale: 1
- _CameraFadingEnabled: 0
- _CameraFarFadeDistance: 2
- _CameraNearFadeDistance: 1
- _ColorMode: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DistortionBlend: 0.5
- _DistortionEnabled: 0
- _DistortionStrength: 1
- _DistortionStrengthScaled: 0
- _DstBlend: 1
- _EmissionEnabled: 0
- _FlipbookMode: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _LightingEnabled: 0
- _Metallic: 0
- _Mode: 4
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SoftParticlesEnabled: 0
- _SoftParticlesFarFadeDistance: 1
- _SoftParticlesNearFadeDistance: 0
- _SpecularHighlights: 1
- _SrcBlend: 5
- _UVSec: 0
- _ZWrite: 0
m_Colors:
- _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0}
- _Color: {r: 0.14249742, g: 0.1318975, b: 0.7169812, a: 1}
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}

8
Assets/Bounds.mat.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 39d0301d3b1720349bf2ce1b81029634
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -7,23 +7,17 @@ using Random = UnityEngine.Random;
using ExtensionMethods;
using UnityEngine.XR;
[ExecuteInEditMode]
public class Monolith : MonoBehaviour
{
// Then monolith the pieces (exist
// = data render and spawn(manual mono -> auto sim)
// input class fed to sim and render
// , then move, then impact)
public Worm leftWorm, rightWorm;
public Piece piece;
public Piece enemy;
public Voxel[] voxels = new Voxel[48];
public int vIndex = 0;
public Worm leftWorm, rightWorm;
public VoxelObject[] voxelObjects;
public Simulate simulate = new Simulate();
public Vhysics vhysics = new Vhysics();
public Render render;
[Header("References")]
@ -31,11 +25,13 @@ public class Monolith : MonoBehaviour
void OnEnable()
{
vhysics.Enable(this);
render.Enable(this);
}
void OnDisable()
{
vhysics.Disable();
render.Disable();
}
@ -67,69 +63,19 @@ public class Monolith : MonoBehaviour
headset = InputDevices.GetDeviceAtXRNode(XRNode.Head);
offCon = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
mainCon = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
testPos = piece.pos + Vector3.forward * 0.4f;
testVel = Vector3.down;
}
Vector3Int Voxelcast(Vector3Int from, Vector3Int step)
{
Vector3Int vPos = from;
int i = 0;
while (i < 15)
{
vPos += step;
if (!InVoxel(vPos))
{
vPos -= step;
break;
}
i++;
}
return vPos;
}
Vector3 testPos;
Vector3Int VoxelPos(Vector3 pos)
public Vector3Int VoxelPos(Vector3 pos)
{
return new Vector3Int(Mathf.RoundToInt(pos.x), Mathf.RoundToInt(pos.y), Mathf.RoundToInt(pos.z));
}
public Vector3 testVel;
float Bound(Vector3 pos, 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 < allDirs.Length; i++)
{
Vector3 d = (Vector3)allDirs[i] * 0.2f;
d[axis] = 0;
Vector3 vPos = Voxelcast(VoxelPos(pos + d), step);
float dist = Mathf.Abs(vPos[axis] - pos[axis]);
if (dist < closest)
{
bound = vPos[axis];
closest = dist;
}
}
// when hit ?
return bound + (0.2f * dir);
}
bool InVoxel(Vector3Int pos)
public bool InVoxel(Vector3Int pos)
{
for (int i = 0; i < voxels.Length; i++)
{
if (voxels[i].pos == pos)
{
return true;
}
if (voxels[i].pos == pos) { return true; }
}
return false;
}
@ -159,6 +105,9 @@ public class Monolith : MonoBehaviour
}
camForm.position = voxelCenter + (camForm.rotation * Vector3.back * 10);
// player
VoxelObject player = voxelObjects[0];
// cursor
Quaternion mainRot = Quaternion.identity;
mainCon.TryGetFeatureValue(CommonUsages.deviceRotation, out mainRot);
@ -171,9 +120,10 @@ public class Monolith : MonoBehaviour
mainRot *= Quaternion.LookRotation(mainDir);
}
Vector3 mainCursor = testPos + (mainRot * Vector3.forward);
Vector3 mainCursor = player.pos + (mainRot * Vector3.forward);
Vector3Int cvPos = VoxelPos(mainCursor);
// mining
bool mainTrigger = false;
mainCon.TryGetFeatureValue(CommonUsages.triggerButton, out mainTrigger);
if (mainTrigger)
@ -190,13 +140,13 @@ public class Monolith : MonoBehaviour
Graphics.DrawMesh(render.meshPieceDebug,
mainCursor, Quaternion.identity,
render.matPieceDebug, 0
render.matObject, 0
);
if (!InVoxel(cvPos))
Graphics.DrawMesh(render.meshPieceDebug,
cvPos, Quaternion.identity,
render.matPieceDebug, 0
render.matObject, 0
);
// Movement
@ -212,211 +162,40 @@ public class Monolith : MonoBehaviour
offRot *= Quaternion.LookRotation(offDir);
}
testVel += offRot * Vector3.forward * offStick.magnitude * 6 * Time.deltaTime;
Vector3 vel = player.voxelBody.velocity;
vel += offRot * Vector3.forward * offStick.magnitude * 6 * Time.deltaTime;
if (offStick.sqrMagnitude == 0)
{
testVel.x *= 1 - (60 * Time.deltaTime);
testVel.z *= 1 - (60 * Time.deltaTime);
vel.x *= 1 - (60 * Time.deltaTime);
vel.z *= 1 - (60 * Time.deltaTime);
}
// jumping ?
mainCon.TryGetFeatureValue(CommonUsages.primaryButton, out jumpBtn);
if (Input.GetKeyDown(KeyCode.Space) || (jumpBtn && Mathf.Abs(testVel.y) < 0.1f))
if (Input.GetKeyDown(KeyCode.Space) || (jumpBtn && Mathf.Abs(vel.y) < 0.1f))
{
testVel.y = 8;
vel.y = 8;
}
// holding
float gravStr = 1;
if ((!Input.GetKey(KeyCode.Space) && !jumpBtn) || testVel.y < 0)
if ((!Input.GetKey(KeyCode.Space) && !jumpBtn) || vel.y < 0)
{
gravStr = 3;
}
testVel.y += -9.81f * gravStr * Time.deltaTime;
testVel = Vector3.ClampMagnitude(testVel, 60);
vel.y += -9.81f * gravStr * Time.deltaTime;
player.voxelBody.velocity = Vector3.ClampMagnitude(vel, 60);
// Graphics.DrawMesh(render.meshPieceDebug,
// voxelPos(testPos), Quaternion.identity,
// render.matPieceDebug, 0
// );
// the refactoring needs to be reconsidered
// I don't want an arbitrary list of VoxelObjects
// I'd like a Player
// an array of each enemy type
// an array of any/each physics object
// bounds/clamp
Vector3 toPos = testPos + testVel * Time.deltaTime;
int w = 0;
while (w < 3)
{
Vector3 clampPos = new Vector3(
Mathf.Clamp(toPos.x, Bound(testPos, 0, -1), Bound(testPos, 0, 1)),
Mathf.Clamp(toPos.y, Bound(testPos, 1, -1), Bound(testPos, 1, 1)),
Mathf.Clamp(toPos.z, Bound(testPos, 2, -1), Bound(testPos, 2, 1))
);
// find smallest clamp
// make only that clamp and clamp check again
// smallest?
// how'bout largest?
float largest = 0;
int largeIndex = -1;
for (int i = 0; i < 3; i++)
{
float dist = Mathf.Abs(toPos[i] - clampPos[i]);
if (dist > largest)
{
largeIndex = i;
largest = dist;
}
}
if (largeIndex > -1)
{
toPos[largeIndex] = clampPos[largeIndex];
testVel[largeIndex] *= -0.25f; // Bounce
// UnityEditor.EditorApplication.isPaused = true;
}
else
{
break;
}
w++;
}
testPos = toPos;
Graphics.DrawMesh(render.meshPieceDebug,
testPos, Quaternion.identity,
render.matPieceDebug, 0
);
// for (int i = 0; i < allDirs.Length; i++)
// {
// Graphics.DrawMesh(render.meshPieceDebug,
// testPos + allDirs[i], Quaternion.identity,
// render.matPieceDebug, 0
// );
// }
return;
// touchPos
// touchDown
// touching
// touchUp
if (Input.GetMouseButtonDown(0))
{
onTouchPos = mousePos;
Vector3 screenCenter = new Vector3(Screen.width / 2, Screen.height / 2, onTouchPos.z);
movePiece = Vector3.Distance(onTouchPos, screenCenter) < 32;
}
if (movePiece)
{
if (Input.GetMouseButtonUp(0) && Vector2.Distance(mousePos, cam.WorldToScreenPoint(piece.pos)) > 32)
{
Vector2 inputAngle = mousePos - cam.WorldToScreenPoint(piece.pos);
float closestAngle = 180;
int dirIndex = 0;
for (int i = 0; i < dirs.Length; i++)
{
float angle = Vector2.Angle(
inputAngle,
cam.WorldToScreenPoint(piece.pos + dirs[i]) - cam.WorldToScreenPoint(piece.pos)
);
// pick out of closest available
if (angle < closestAngle && !Outside(piece.pos + dirs[i]))
{
dirIndex = i;
closestAngle = angle;
}
}
if (closestAngle < 60)
{
while (!Outside(piece.pos))
{
piece.pos += dirs[dirIndex];
}
piece.pos -= dirs[dirIndex];
if (piece.pos == enemy.pos)
{
enemy.pos = voxels[Random.Range(0, voxels.Length)].pos;
}
}
movePiece = false;
}
camAngleVel = Vector2.zero;
}
else
{
if (Input.GetMouseButton(0))
{
Vector3 offset = (mousePos - oldTouchPos) / 3f;
camAngleVel = new Vector2(-offset.y, offset.x) / Time.deltaTime;
if (camAngleVel.sqrMagnitude > 0 || delay < Time.time)
{
oldCamAngleVel = camAngleVel;
delay = Time.time + 0.1f;
}
}
else
{
camAngleVel *= 1 - (6 * Time.deltaTime);
}
if (Input.GetMouseButtonUp(0))
{
camAngleVel = oldCamAngleVel;
}
}
camAngle += camAngleVel * Time.deltaTime;
camAngle.x = Mathf.Clamp(camAngle.x, -60f, 60f);
camForm.rotation = Quaternion.Euler(Vector3.up * camAngle.y) * Quaternion.Euler(Vector3.right * camAngle.x);
oldTouchPos = mousePos;
// vr chess? infinite dungeon crawler ZENCORE
// just 3d the movement patterns
// twist cursor game
// input is none
// simulate is monolithed entirely
// part of simulate is to generate the level
// pathing needs a refactor
// we learned quite a bit
// what paths are interesting in 3D?
// build for that, don't just translate chess movement patterns
// chess takeaways
// long shots from well placed pieces
// hook shots from knights
// consider gravities constraints
// fall | cling walls | cling ceiling
// jump | climb fly |
// what do I want to do?
camPivot = render.lerpPos;
camForm.position = camPivot + Quaternion.LookRotation(camForm.rotation * Vector3.forward) * Vector3.back * 24;
vhysics.Update();
render.Update();
}
Vector3 camPivot;
[HideInInspector]
public Vector3Int[] dirs = new Vector3Int[] {
new Vector3Int(-1, 0, 0), new Vector3Int(0, -1, 0), new Vector3Int(0, 0, -1),
@ -482,17 +261,23 @@ public class Worm
}
[Serializable]
public class Piece
public class VoxelObject
{
public Vector3Int pos;
public int[] pattern;
// a pattern is the change in dirIndex at x Step
// cant be a dir change at zero
public Vector3 pos;
public Quaternion rot;
public float scale;
public Piece(Vector3Int pos)
{
this.pos = pos;
}
public VoxelBody voxelBody;
public Mesh mesh;
}
[Serializable]
public class VoxelBody
{
public float boundRadius;
public Vector3 velocity;
// public float mass;
}
namespace ExtensionMethods

View file

@ -7,7 +7,7 @@ Material:
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Piece
m_Name: Object
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4

View file

@ -12,46 +12,54 @@ public class Render
public void Enable(Monolith mono)
{
this.mono = mono;
Camera.onPreCull -= DrawWithCamera;
Camera.onPreCull += DrawWithCamera;
}
public void Disable()
{
Camera.onPreCull -= DrawWithCamera;
}
public Mesh meshVoxelDebug, meshPieceDebug;
public Material matVoxelDebug, matPieceDebug, matEnemy, matPath;
public Mesh meshVoxelDebug, meshPieceDebug, meshCube;
public Material matVoxelDebug, matObject, matBounds, matEnemy, matPath;
void DrawWithCamera(Camera camera)
{
if (camera)
{
// GL.Clear(true, true, Color.gray);
Draw(camera, camera.transform.localToWorldMatrix * Matrix4x4.TRS(Vector3.forward * 10, Quaternion.identity, Vector3.one));
}
}
public Vector3 lerpPos;
void Draw(Camera camera, Matrix4x4 matrix)
Matrix4x4 tempM4 = new Matrix4x4();
public void Update()
{
Voxels();
for (int i = 0; i < mono.voxelObjects.Length; i++)
{
VoxelObject voxelObject = mono.voxelObjects[i];
// render voxelbody bounds
if (voxelObject.voxelBody != null)
{
tempM4.SetTRS(
voxelObject.pos,
Quaternion.identity,
Vector3.one * voxelObject.voxelBody.boundRadius * 2
);
Graphics.DrawMesh(meshCube, tempM4, matBounds, 0);
}
// render voxelobject mesh
if (voxelObject.mesh != null)
{
voxelObject.rot.Normalize();
Graphics.DrawMesh(voxelObject.mesh,
voxelObject.pos, voxelObject.rot,
matObject, 0
);
}
}
// Draw Enemy
Graphics.DrawMesh(meshPieceDebug,
mono.enemy.pos,
Quaternion.identity,
matEnemy, 0
);
// Graphics.DrawMesh(meshPieceDebug,
// mono.enemy.pos,
// Quaternion.identity,
// matEnemy, 0
// );
// Draw Piece
lerpPos = Vector3.Lerp(lerpPos, mono.piece.pos, Time.deltaTime * 24);
Graphics.DrawMesh(meshPieceDebug,
lerpPos,
Quaternion.identity,
matPieceDebug, 0
);
// Draw Path...(s)
// lets start constraining the movement to the generated level
@ -60,48 +68,6 @@ public class Render
// {
// Paths(i, mono.piece.pos);
// }
for (int i = 0; i < mono.dirs.Length; i++)
{
if (mono.movePiece && !mono.Outside(mono.piece.pos + mono.dirs[i]))
{
Graphics.DrawMesh(meshPieceDebug,
mono.piece.pos + mono.dirs[i],
Quaternion.identity,
matPath, 0
);
}
}
}
void Paths(int dirIndex, Vector3Int pos, int patternIndex = 0)
{
for (int i = patternIndex; i < mono.piece.pattern.Length; i++)
{
pos += mono.dirs[dirIndex];
if (mono.Outside(pos))
{
return;
}
else
{
Graphics.DrawMesh(meshPieceDebug,
pos,
Quaternion.identity,
matPath, 0
);
}
if (i != patternIndex && mono.piece.pattern[i] != 0)
{
int toIndex = dirIndex.Rollover(mono.piece.pattern[i], mono.dirs.Length);
Paths(toIndex, pos, i);
Paths(toIndex.Rollover(2, mono.dirs.Length), pos, i);
Paths(toIndex.Rollover(3, mono.dirs.Length), pos, i);
Paths(toIndex.Rollover(5, mono.dirs.Length), pos, i);
return;
}
}
}
List<Matrix4x4> voxelM4 = new List<Matrix4x4>();

View file

@ -146,7 +146,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 344952468}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 100, z: 0}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
@ -164,18 +164,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 6fd8fe86f7d15534b899a0bba18bfab1, type: 3}
m_Name:
m_EditorClassIdentifier:
leftWorm:
pos: {x: 1, y: 4, z: 5}
dirIndex: 1
rightWorm:
pos: {x: 1, y: 2, z: 5}
dirIndex: 4
piece:
pos: {x: -1, y: 1, z: 4}
pattern: 000000000000000000000000
enemy:
pos: {x: 0, y: 0, z: 0}
pattern:
voxels:
- pos: {x: -2, y: -2, z: 2}
- pos: {x: -2, y: -1, z: 2}
@ -226,18 +214,33 @@ MonoBehaviour:
- pos: {x: -2, y: -2, z: 1}
- pos: {x: -1, y: -2, z: 1}
vIndex: 36
leftWorm:
pos: {x: 1, y: 4, z: 5}
dirIndex: 1
rightWorm:
pos: {x: 1, y: 2, z: 5}
dirIndex: 4
voxelObjects:
- pos: {x: 0, y: 0, z: 0}
rot: {x: 0, y: 0, z: 0, w: 1}
scale: 1
voxelBody:
boundRadius: 0.32
velocity: {x: 0, y: 0, z: 0}
mesh: {fileID: 8102167970221282723, guid: f17ff0e1c561a0a4bba0f4c3bb139cc4, type: 3}
render:
meshVoxelDebug: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
meshPieceDebug: {fileID: 8102167970221282723, guid: f17ff0e1c561a0a4bba0f4c3bb139cc4,
type: 3}
meshCube: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
matVoxelDebug: {fileID: 2100000, guid: 38b6b77574398c54498e524a886902e7, type: 2}
matPieceDebug: {fileID: 2100000, guid: 16daa9ed715d7874db42629f4e3e0eef, type: 2}
matObject: {fileID: 2100000, guid: 16daa9ed715d7874db42629f4e3e0eef, type: 2}
matBounds: {fileID: 2100000, guid: 39d0301d3b1720349bf2ce1b81029634, type: 2}
matEnemy: {fileID: 2100000, guid: d9312e72de6721d41975fc093421fc2f, type: 2}
matPath: {fileID: 2100000, guid: 525b9c2ebdaac4440b94ea0fa8ca42dd, type: 2}
lerpPos: {x: -1, y: 1, z: 4}
cam: {fileID: 963194227}
testVel: {x: 0, y: 2.8496501, z: 0}
movePiece: 0
voxelCenter: {x: 0, y: 0, z: 0}
dirs:
- {x: -1, y: 0, z: 0}
- {x: 0, y: -1, z: 0}
@ -245,6 +248,25 @@ MonoBehaviour:
- {x: 1, y: 0, z: 0}
- {x: 0, y: 1, z: 0}
- {x: 0, y: 0, z: 1}
allDirs:
- {x: -1, y: 0, z: 0}
- {x: 0, y: -1, z: 0}
- {x: 0, y: 0, z: -1}
- {x: -1, y: -1, z: 0}
- {x: 0, y: -1, z: -1}
- {x: -1, y: 0, z: -1}
- {x: 1, y: 0, z: 0}
- {x: 0, y: 1, z: 0}
- {x: 0, y: 0, z: 1}
- {x: 1, y: 1, z: 0}
- {x: 0, y: 1, z: 1}
- {x: 1, y: 0, z: 1}
- {x: -1, y: 1, z: 0}
- {x: 0, y: -1, z: 1}
- {x: 1, y: 0, z: -1}
- {x: 1, y: -1, z: 0}
- {x: 0, y: 1, z: -1}
- {x: -1, y: 0, z: 1}
--- !u!1 &705507993
GameObject:
m_ObjectHideFlags: 0
@ -415,7 +437,7 @@ Transform:
m_GameObject: {fileID: 963194225}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 10, y: 10, z: 10}
m_LocalScale: {x: 20, y: 20, z: 20}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0

129
Assets/Vhysics.cs Normal file
View file

@ -0,0 +1,129 @@
using System;
using UnityEngine;
[Serializable]
public class Vhysics
{
Monolith mono;
public void Enable(Monolith mono)
{
this.mono = mono;
}
public void Disable()
{
}
public void Update()
{
// bounds
for (int i = 0; i < mono.voxelObjects.Length; i++)
{
VoxelObject vobj = mono.voxelObjects[i];
if (vobj.voxelBody != null)
{
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;
// hit checks
for (int j = 0; j < mono.voxelObjects.Length; j++)
{
// space voxelBodys
VoxelObject otherObject = mono.voxelObjects[j];
if (i != j && otherObject.voxelBody != null)
{
Vector3 delta = otherObject.pos - vobj.pos;
// if (delta.magnitude < )
// {
// otherObject.voxelBody.velocity += ;
// }
}
}
}
}
// FAT
// rectangular bounds
// larger than one voxel
}
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;
}
}

11
Assets/Vhysics.cs.meta Normal file
View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39c6f64f3ffb3054aba984c01bb03658
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: