Skip to content

Commit

Permalink
Barclah/physics/jointing (#960)
Browse files Browse the repository at this point in the history
  • Loading branch information
HunterBarclay authored Mar 14, 2024
2 parents baab969 + 8dfabc2 commit cbbd389
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 139 deletions.
6 changes: 0 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
[submodule "mirabuf"]
path = mirabuf
url = https://github.com/HiceS/mirabuf
[submodule "web/engine/vendor/protobuf"]
path = web/engine/vendor/protobuf
url = https://github.com/protocolbuffers/protobuf
[submodule "web/engine/vendor/JoltPhysics"]
path = web/engine/vendor/JoltPhysics
url = https://github.com/jrouwe/JoltPhysics
8 changes: 4 additions & 4 deletions fission/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion fission/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"test": "vitest"
},
"dependencies": {
"@barclah/jolt-physics": "^0.16.1",
"@barclah/jolt-physics": "^0.16.2",
"@react-three/drei": "^9.96.5",
"@react-three/fiber": "^8.15.15",
"@types/node": "^20.10.6",
Expand Down
14 changes: 7 additions & 7 deletions fission/src/graphics/JoltExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import JOLT from '../util/loading/JoltSyncLoader.ts';

import { useEffect, useRef } from 'react';
import React from 'react';
import { random } from '../util/Random.ts';
import { Random } from '../util/Random.ts';

const clock = new THREE.Clock();
let time = 0;
Expand Down Expand Up @@ -303,19 +303,19 @@ function spawnRandomCubes(time, deltaTime) {
}

function getRandomQuat() {
let vec = new JOLT.Vec3(0.001 + random(), random(), random());
let quat = JOLT.Quat.prototype.sRotation(vec.Normalized(), 2 * Math.PI * random());
let vec = new JOLT.Vec3(0.001 + Random(), Random(), Random());
let quat = JOLT.Quat.prototype.sRotation(vec.Normalized(), 2 * Math.PI * Random());
JOLT.destroy(vec);
return quat;
}

function makeRandomBox() {
let pos = new JOLT.Vec3((random() - 0.5) * 25, 15, (random() - 0.5) * 25);
let pos = new JOLT.Vec3((Random() - 0.5) * 25, 15, (Random() - 0.5) * 25);
let rot = getRandomQuat();

let x = random();
let y = random();
let z = random();
let x = Random();
let y = Random();
let z = Random();
let size = new JOLT.Vec3(x, y, z);
let shape = new JOLT.BoxShape(size, 0.05, undefined);
let creationSettings = new JOLT.BodyCreationSettings(shape, pos, rot, JOLT.EMotionType_Dynamic, LAYER_MOVING);
Expand Down
7 changes: 7 additions & 0 deletions fission/src/jolt/Wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class Jolt_Shape {

}

export class Jolt_ConvexShape extends Jolt_Shape {

}
1 change: 0 additions & 1 deletion fission/src/systems/Systems.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./physics/PhysicsSystem";
export * from "./world/WorldSystem";
export * from "./rendering/RenderSystem";
134 changes: 103 additions & 31 deletions fission/src/systems/physics/PhysicsSystem.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import { ThreeQuaternion_JoltQuat, ThreeVector3_JoltVec3, _JoltQuat } from "../../util/conversions/JoltThreeConversions";
import JOLT, { JOLT_TYPES } from "../../util/loading/JoltAsyncLoader";
import { ThreeVector3_JoltVec3, _JoltQuat } from "../../util/TypeConversions";
import JOLT from "../../util/loading/JoltSyncLoader";
import Jolt from "@barclah/jolt-physics";
import * as THREE from 'three';

const LAYER_NOT_MOVING = 0;
const LAYER_MOVING = 1;
const COUNT_OBJECT_LAYERS = 2;

const STANDARD_TIME_STEP = 1.0 / 60.0;
const STANDARD_SUB_STEPS = 1;

/**
* The PhysicsSystem handles all Jolt Phyiscs interactions within Synthesis.
* This system can create physical representations of objects such as Robots,
* Fields, and Game pieces, and simulate them.
*/
export class PhysicsSystem {

private _joltInterface;
private _joltPhysSystem;
private _joltBodyInterface;
private _bodies: Array<any>;
private _joltInterface: Jolt.JoltInterface;
private _joltPhysSystem: Jolt.PhysicsSystem;
private _joltBodyInterface: Jolt.BodyInterface;
private _bodies: Array<Jolt.Body>;

/**
* Creates a PhysicsSystem object.
*/
constructor() {
if (!JOLT) { throw new Error("Must await `joltInit`") }
this._bodies = [];

var joltSettings = new JOLT.JoltSettings();
setupCollisionFiltering(joltSettings);
const joltSettings = new JOLT.JoltSettings();
SetupCollisionFiltering(joltSettings);

this._joltInterface = new JOLT.JoltInterface(joltSettings);
JOLT.destroy(joltSettings);
Expand All @@ -26,58 +38,118 @@ export class PhysicsSystem {
this._joltBodyInterface = this._joltPhysSystem.GetBodyInterface();
}

public createBox(
/**
* TEMPORARY
* Create a box.
*
* @param halfExtents The half extents of the Box.
* @param mass Mass of the Box. Leave undefined to make Box static.
* @param position Posiition of the Box (default: 0, 0, 0)
* @param rotation Rotation of the Box (default 0, 0, 0, 1)
* @returns Reference to Jolt Body
*/
public CreateBox(
halfExtents: THREE.Vector3,
mass: number | undefined,
position: THREE.Vector3 | undefined,
rotation: THREE.Euler | THREE.Quaternion | undefined) {
var size = ThreeVector3_JoltVec3(halfExtents);
var shape = new JOLT!.BoxShape(size, 0.1);
JOLT!.destroy(size);
const size = ThreeVector3_JoltVec3(halfExtents);
const shape = new JOLT.BoxShape(size, 0.1);
JOLT.destroy(size);

var pos = position ? ThreeVector3_JoltVec3(position) : new JOLT!.Vec3(0.0, 0.0, 0.0);
var rot = _JoltQuat(rotation);
let creationSettings = new JOLT!.BodyCreationSettings(
const pos = position ? ThreeVector3_JoltVec3(position) : new JOLT.Vec3(0.0, 0.0, 0.0);
const rot = _JoltQuat(rotation);
const creationSettings = new JOLT.BodyCreationSettings(
shape,
pos,
rot,
mass ? JOLT!.EMotionType_Dynamic : JOLT!.EMotionType_Static,
mass ? JOLT.EMotionType_Dynamic : JOLT.EMotionType_Static,
LAYER_NOT_MOVING
);
if (mass) {
creationSettings.mMassPropertiesOverride.mMass = mass;
}
let body = this._joltBodyInterface.CreateBody(creationSettings);
JOLT!.destroy(pos);
JOLT!.destroy(rot);
JOLT!.destroy(creationSettings);
const body = this._joltBodyInterface.CreateBody(creationSettings);
JOLT.destroy(pos);
JOLT.destroy(rot);
JOLT.destroy(creationSettings);

this._bodies.push(body);
return body;
}
}

function setupCollisionFiltering(settings) {
if (!JOLT) { throw new Error("Must await `joltInit`") }
public CreateBody(
shape: Jolt.Shape,
mass: number | undefined,
position: THREE.Vector3 | undefined,
rotation: THREE.Euler | THREE.Quaternion | undefined) {
const pos = position ? ThreeVector3_JoltVec3(position) : new JOLT.Vec3(0.0, 0.0, 0.0);
const rot = _JoltQuat(rotation);
const creationSettings = new JOLT.BodyCreationSettings(
shape,
pos,
rot,
mass ? JOLT.EMotionType_Dynamic : JOLT.EMotionType_Static,
LAYER_NOT_MOVING
);
if (mass) {
creationSettings.mMassPropertiesOverride.mMass = mass;
}
const body = this._joltBodyInterface.CreateBody(creationSettings);
JOLT.destroy(pos);
JOLT.destroy(rot);
JOLT.destroy(creationSettings);

this._bodies.push(body);
return body;
}

public CreateConvexHull(points: Float32Array, density: number = 1.0) {
if (points.length % 3) {
throw new Error(`Invalid size of points: ${points.length}`);
}
const settings = new JOLT.ConvexHullShapeSettings();
settings.mPoints.clear();
settings.mPoints.reserve(points.length / 3.0);
for (let i = 0; i < points.length; i += 3) {
settings.mPoints.push_back(new JOLT.Vec3(points[i], points[i + 1], points[i + 2]));
}
settings.mDensity = density;
return settings.Create();
}

public Step() {
this._joltInterface.Step(STANDARD_TIME_STEP, STANDARD_SUB_STEPS);
}

public Destroy() {
// Destroy Jolt Bodies.
this._bodies.forEach(x => JOLT.destroy(x));
this._bodies = [];

JOLT.destroy(this._joltInterface);
}
}

let objectFilter = new JOLT.ObjectLayerPairFilterTable(COUNT_OBJECT_LAYERS);
function SetupCollisionFiltering(settings: Jolt.JoltSettings) {
const objectFilter = new JOLT.ObjectLayerPairFilterTable(COUNT_OBJECT_LAYERS);
objectFilter.EnableCollision(LAYER_NOT_MOVING, LAYER_MOVING);
objectFilter.EnableCollision(LAYER_MOVING, LAYER_MOVING);

const BP_LAYER_NOT_MOVING = new JOLT.BroadPhaseLayer(LAYER_NOT_MOVING);
const BP_LAYER_MOVING = new JOLT.BroadPhaseLayer(LAYER_MOVING);
const COUNT_BROAD_PHASE_LAYERS = 2;

let bpInterface = new JOLT.BroadPhaseLayerInterfaceTable(COUNT_OBJECT_LAYERS, COUNT_BROAD_PHASE_LAYERS);
const bpInterface = new JOLT.BroadPhaseLayerInterfaceTable(COUNT_OBJECT_LAYERS, COUNT_BROAD_PHASE_LAYERS);
bpInterface.MapObjectToBroadPhaseLayer(LAYER_NOT_MOVING, BP_LAYER_NOT_MOVING);
bpInterface.MapObjectToBroadPhaseLayer(LAYER_MOVING, BP_LAYER_MOVING);

this._joltSettings.mObjectLayerPairFilter = objectFilter;
this._joltSettings.mBroadPhaseLayerInterface = bpInterface;
this._joltSettings.mObjectVsBroadPhaseLayerFilter = new JOLT.ObjectVsBroadPhaseLayerFilterTable(
this._joltSettings.mBroadPhaseLayerInterface,
settings.mObjectLayerPairFilter = objectFilter;
settings.mBroadPhaseLayerInterface = bpInterface;
settings.mObjectVsBroadPhaseLayerFilter = new JOLT.ObjectVsBroadPhaseLayerFilterTable(
settings.mBroadPhaseLayerInterface,
COUNT_BROAD_PHASE_LAYERS,
this._joltSettings.mObjectLayerPairFilter,
settings.mObjectLayerPairFilter,
COUNT_OBJECT_LAYERS
);
}
51 changes: 0 additions & 51 deletions fission/src/systems/world/WorldSystem.ts
Original file line number Diff line number Diff line change
@@ -1,51 +0,0 @@
import { Type } from "typescript";
import Queue from "../../util/data/Queue";
import { PhysicsSystem, RenderSystem } from "../Systems";

class WorldSystem {

private _lastFrameTime: number;
private _updateFrame?: number;

private _physics: PhysicsSystem;
private _renderer: RenderSystem;

constructor() {
this._physics = new PhysicsSystem();
this._renderer = new RenderSystem();

// Create Robot
}

public startLoop() {
this.stopLoop();


}

private update() {
var _ = Date.now() - this._lastFrameTime;
this._lastFrameTime = Date.now();

this._updateFrame = requestAnimationFrame(this.update);


}

public stopLoop() {

}

}
export var worldSystem = new WorldSystem();

export abstract class System {

private _priority: number;

protected get priority() { return this._priority; }

protected constructor(priority: number) {

}
}
64 changes: 64 additions & 0 deletions fission/src/test/PhysicsSystem.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { test, expect, describe, assert } from 'vitest';
import { PhysicsSystem } from '../systems/Systems';

describe('Physics System Tests', () => {
test('Convex Hull Shape (Cube)', () => {
const points: Float32Array = new Float32Array(
[
0.5, -0.5, 0.5,
-0.5, -0.5, 0.5,
-0.5, -0.5, -0.5,
0.5, -0.5, -0.5,
0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
]
);

const system = new PhysicsSystem();
const shapeResult = system.CreateConvexHull(points);

assert(shapeResult.HasError() == false, shapeResult.GetError().c_str());
expect(shapeResult.IsValid()).toBe(true);

const shape = shapeResult.Get();

expect(shape.GetVolume() - 1.0).toBeLessThan(0.001);
expect(shape.GetCenterOfMass().Length()).toBe(0.0);

shape.Release();
system.Destroy();

});
test('Convex Hull Shape (Tetrahedron)', () => {
const points: Float32Array = new Float32Array(
[
0.0, 0.0, 0.0,
0.0, 1.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0
]
);

const system = new PhysicsSystem();
const shapeResult = system.CreateConvexHull(points);

assert(shapeResult.HasError() == false, shapeResult.GetError().c_str());
expect(shapeResult.IsValid()).toBe(true);

const shape = shapeResult.Get();
const bounds = shape.GetLocalBounds();
const boxSize = bounds.mMax.Sub(bounds.mMin);

expect(boxSize.GetX() - 1.0).toBeLessThan(0.001);
expect(boxSize.GetY() - 1.0).toBeLessThan(0.001);
expect(boxSize.GetZ() - 1.0).toBeLessThan(0.001);
expect(shape.GetVolume() - (1.0 / 6.0)).toBeLessThan(0.001);
expect(shape.GetMassProperties().mMass - 6.0).toBeLessThan(0.001);

shape.Release();
system.Destroy();
});
});
Loading

0 comments on commit cbbd389

Please sign in to comment.