Update framework
This commit is contained in:
2
framework/physics/aabb.d.ts
vendored
Normal file
2
framework/physics/aabb.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import { PhysicsObject } from './object';
|
||||
export declare function AABB(obj1: PhysicsObject, obj2: PhysicsObject): boolean;
|
17
framework/physics/aabb.js
Normal file
17
framework/physics/aabb.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export function AABB(obj1, obj2) {
|
||||
if (checkOverlap(obj1.position.x, obj1.dimensions.x, obj2.position.x, obj2.dimensions.x)) {
|
||||
return true;
|
||||
}
|
||||
else if (checkOverlap(obj1.position.y, obj1.dimensions.y, obj2.position.y, obj2.dimensions.y)) {
|
||||
return true;
|
||||
}
|
||||
else if (checkOverlap(obj1.position.z, obj1.dimensions.z, obj2.position.z, obj2.dimensions.z)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function checkOverlap(x, w, yx, yw) {
|
||||
if (x > yx || x < yx + yw || x + w > x || x + w < yx + yw) {
|
||||
return true;
|
||||
}
|
||||
}
|
0
framework/physics/index.d.ts
vendored
Normal file
0
framework/physics/index.d.ts
vendored
Normal file
0
framework/physics/index.js
Normal file
0
framework/physics/index.js
Normal file
7
framework/physics/object.d.ts
vendored
Normal file
7
framework/physics/object.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Vec3 } from './vec3';
|
||||
export declare class PhysicsObject {
|
||||
position: Vec3;
|
||||
dimensions: Vec3;
|
||||
velocity: Vec3;
|
||||
affectedByGravity: boolean;
|
||||
}
|
2
framework/physics/object.js
Normal file
2
framework/physics/object.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export class PhysicsObject {
|
||||
}
|
39
framework/physics/octree.d.ts
vendored
Normal file
39
framework/physics/octree.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { PhysicsObject } from './object';
|
||||
import { Vec3 } from './vec3';
|
||||
export declare class Octree {
|
||||
private dimensions;
|
||||
private maxObjects;
|
||||
private maxLevels;
|
||||
root: OcTreeNode;
|
||||
constructor(dimensions: Vec3, maxObjects?: number, maxLevels?: number);
|
||||
insert(obj: PhysicsObject): void;
|
||||
find(position: Vec3, dimensions: Vec3): PhysicsObject[];
|
||||
}
|
||||
export declare class OcTreeNode {
|
||||
private position;
|
||||
private dimensions;
|
||||
private maxLevels;
|
||||
private maxObjects;
|
||||
private currentLevel;
|
||||
objects: PhysicsObject[];
|
||||
nodes: OcTreeNode[];
|
||||
constructor(position: Vec3, dimensions: Vec3, maxLevels: number, maxObjects: number, currentLevel?: number);
|
||||
insert(obj: PhysicsObject): any;
|
||||
find(x: number, y: number, z: number, xw: number, yh: number, zd: number): PhysicsObject[];
|
||||
split(): void;
|
||||
private distributeObjectsToNodes;
|
||||
getIndex(x: number, y: number, z: number): Direction;
|
||||
getIndeciesForRect(x: number, y: number, z: number, xw: number, yh: number, zd: number): Direction[];
|
||||
}
|
||||
declare enum Direction {
|
||||
AboveUpperLeft = 0,
|
||||
AboveUpperRight = 1,
|
||||
AboveLowerRight = 2,
|
||||
AboveLowerLeft = 3,
|
||||
BelowUpperLeft = 4,
|
||||
BelowUpperRight = 5,
|
||||
BelowLowerRight = 6,
|
||||
BelowLowerLeft = 7,
|
||||
Here = 8
|
||||
}
|
||||
export {};
|
206
framework/physics/octree.js
Normal file
206
framework/physics/octree.js
Normal file
@@ -0,0 +1,206 @@
|
||||
import { Vec3 } from './vec3';
|
||||
export class Octree {
|
||||
constructor(dimensions, maxObjects = 10, maxLevels = 10) {
|
||||
this.dimensions = dimensions;
|
||||
this.maxObjects = maxObjects;
|
||||
this.maxLevels = maxLevels;
|
||||
this.root = new OcTreeNode(new Vec3({
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}), this.dimensions, maxLevels, maxObjects, 0);
|
||||
}
|
||||
insert(obj) {
|
||||
this.root.insert(obj);
|
||||
}
|
||||
find(position, dimensions) {
|
||||
return this.root.find(position.x, position.y, position.z, dimensions.x, dimensions.y, dimensions.z);
|
||||
}
|
||||
}
|
||||
export class OcTreeNode {
|
||||
constructor(position, dimensions, maxLevels, maxObjects, currentLevel = 0) {
|
||||
this.position = position;
|
||||
this.dimensions = dimensions;
|
||||
this.maxLevels = maxLevels;
|
||||
this.maxObjects = maxObjects;
|
||||
this.currentLevel = currentLevel;
|
||||
this.objects = [];
|
||||
this.nodes = [];
|
||||
}
|
||||
insert(obj) {
|
||||
const index = this.getIndex(obj.position.x, obj.position.y, obj.position.z);
|
||||
if (index === Direction.Here) {
|
||||
this.objects.push(obj);
|
||||
}
|
||||
else {
|
||||
return this.nodes[index].insert(obj);
|
||||
}
|
||||
if (this.objects.length > this.maxObjects &&
|
||||
this.currentLevel < this.maxLevels) {
|
||||
this.split();
|
||||
}
|
||||
}
|
||||
find(x, y, z, xw, yh, zd) {
|
||||
if (this.nodes.length < 1) {
|
||||
return this.objects;
|
||||
}
|
||||
const indecies = this.getIndeciesForRect(x, y, z, xw, yh, zd);
|
||||
let results = [];
|
||||
for (let i = 0; i < indecies.length - 1; i++) {
|
||||
let res = this.nodes[indecies[i]].find(x, y, z, xw, yh, zd);
|
||||
results.push([...res]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
split() {
|
||||
const halfWidth = this.dimensions.x / 2;
|
||||
const halfHeight = this.dimensions.y / 2;
|
||||
const halfDepth = this.dimensions.z / 2;
|
||||
this.nodes[Direction.AboveUpperLeft] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.AboveUpperRight] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.AboveLowerRight] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.AboveLowerLeft] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.BelowUpperLeft] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.BelowUpperRight] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.BelowLowerRight] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.nodes[Direction.BelowLowerLeft] = new OcTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects, this.currentLevel++);
|
||||
this.distributeObjectsToNodes();
|
||||
}
|
||||
distributeObjectsToNodes() {
|
||||
if (this.nodes.length < 8) {
|
||||
this.split();
|
||||
return;
|
||||
}
|
||||
this.objects.forEach((obj) => {
|
||||
const direction = this.getIndex(obj.position.x, obj.position.y, obj.position.z);
|
||||
this.nodes[direction].insert(obj);
|
||||
});
|
||||
this.objects = [];
|
||||
}
|
||||
getIndex(x, y, z) {
|
||||
if (this.nodes.length === 0) {
|
||||
return Direction.Here;
|
||||
}
|
||||
const halfWidth = this.dimensions.x / 2;
|
||||
const halfHeight = this.dimensions.y / 2;
|
||||
const halfDepth = this.dimensions.z / 2;
|
||||
const isBelow = z < this.position.z + halfDepth;
|
||||
const isLeft = x < this.position.x + halfWidth;
|
||||
const isUpper = y > this.position.y + halfHeight;
|
||||
if (isBelow) {
|
||||
if (isLeft) {
|
||||
if (isUpper)
|
||||
return Direction.AboveUpperLeft;
|
||||
else
|
||||
return Direction.AboveLowerLeft;
|
||||
}
|
||||
else {
|
||||
if (isUpper)
|
||||
return Direction.AboveUpperRight;
|
||||
else
|
||||
return Direction.AboveLowerRight;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isLeft) {
|
||||
if (isUpper)
|
||||
return Direction.BelowUpperLeft;
|
||||
else
|
||||
return Direction.BelowLowerLeft;
|
||||
}
|
||||
else {
|
||||
if (isUpper)
|
||||
return Direction.BelowUpperRight;
|
||||
else
|
||||
return Direction.BelowLowerRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
getIndeciesForRect(x, y, z, xw, yh, zd) {
|
||||
if (!(x > this.position.x && x < this.position.x + this.dimensions.x) ||
|
||||
!(y > this.position.y && y < this.position.y + this.dimensions.y) ||
|
||||
!(z > this.position.z && z < this.position.z + this.dimensions.z)) {
|
||||
return [];
|
||||
}
|
||||
let indecies = [];
|
||||
indecies.push(this.getIndex(x, y, z));
|
||||
indecies.push(this.getIndex(x + xw, y + yh, z + zd));
|
||||
return indecies;
|
||||
}
|
||||
}
|
||||
var Direction;
|
||||
(function (Direction) {
|
||||
Direction[Direction["AboveUpperLeft"] = 0] = "AboveUpperLeft";
|
||||
Direction[Direction["AboveUpperRight"] = 1] = "AboveUpperRight";
|
||||
Direction[Direction["AboveLowerRight"] = 2] = "AboveLowerRight";
|
||||
Direction[Direction["AboveLowerLeft"] = 3] = "AboveLowerLeft";
|
||||
Direction[Direction["BelowUpperLeft"] = 4] = "BelowUpperLeft";
|
||||
Direction[Direction["BelowUpperRight"] = 5] = "BelowUpperRight";
|
||||
Direction[Direction["BelowLowerRight"] = 6] = "BelowLowerRight";
|
||||
Direction[Direction["BelowLowerLeft"] = 7] = "BelowLowerLeft";
|
||||
Direction[Direction["Here"] = 8] = "Here";
|
||||
})(Direction || (Direction = {}));
|
38
framework/physics/octtree.d.ts
vendored
Normal file
38
framework/physics/octtree.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { PhysicsObject } from "./object";
|
||||
import { Vec3 } from "./vec3";
|
||||
export declare class Octtree {
|
||||
private dimensions;
|
||||
private maxObjects;
|
||||
private maxLevels;
|
||||
root: OctTreeNode;
|
||||
constructor(dimensions: Vec3, maxObjects?: number, maxLevels?: number);
|
||||
insert(obj: PhysicsObject): void;
|
||||
find(position: Vec3, dimensions: Vec3): PhysicsObject[];
|
||||
}
|
||||
export declare class OctTreeNode {
|
||||
private position;
|
||||
private dimensions;
|
||||
private maxLevels;
|
||||
private maxObjects;
|
||||
objects: PhysicsObject[];
|
||||
nodes: OctTreeNode[];
|
||||
constructor(position: Vec3, dimensions: Vec3, maxLevels: number, maxObjects: number);
|
||||
insert(obj: PhysicsObject): void;
|
||||
find(position: Vec3, dimensions: Vec3): PhysicsObject[];
|
||||
split(): void;
|
||||
private distributeObjectsToNodes;
|
||||
getIndex(x: number, y: number, z: number): Direction;
|
||||
getIndeciesForRect(position: Vec3, dimensions: Vec3): Set<Direction>;
|
||||
}
|
||||
declare enum Direction {
|
||||
AboveUpperLeft = 0,
|
||||
AboveUpperRight = 1,
|
||||
AboveLowerRight = 2,
|
||||
AboveLowerLeft = 3,
|
||||
BelowUpperLeft = 4,
|
||||
BelowUpperRight = 5,
|
||||
BelowLowerRight = 6,
|
||||
BelowLowerLeft = 7,
|
||||
Here = 8
|
||||
}
|
||||
export {};
|
193
framework/physics/octtree.js
Normal file
193
framework/physics/octtree.js
Normal file
@@ -0,0 +1,193 @@
|
||||
import { Vec3 } from "./vec3";
|
||||
export class Octtree {
|
||||
constructor(dimensions, maxObjects = 10, maxLevels = 10) {
|
||||
this.dimensions = dimensions;
|
||||
this.maxObjects = maxObjects;
|
||||
this.maxLevels = maxLevels;
|
||||
this.root = new OctTreeNode(new Vec3({
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}), this.dimensions, maxLevels, maxObjects);
|
||||
}
|
||||
insert(obj) {
|
||||
this.root.insert(obj);
|
||||
}
|
||||
find(position, dimensions) {
|
||||
return this.root.find(position, dimensions);
|
||||
}
|
||||
}
|
||||
export class OctTreeNode {
|
||||
constructor(position, dimensions, maxLevels, maxObjects) {
|
||||
this.position = position;
|
||||
this.dimensions = dimensions;
|
||||
this.maxLevels = maxLevels;
|
||||
this.maxObjects = maxObjects;
|
||||
this.objects = [];
|
||||
this.nodes = [];
|
||||
}
|
||||
insert(obj) {
|
||||
this.objects.push(obj);
|
||||
if (this.objects.length > this.maxObjects) {
|
||||
this.split();
|
||||
}
|
||||
}
|
||||
find(position, dimensions) {
|
||||
if (!this.nodes.length) {
|
||||
return this.objects;
|
||||
}
|
||||
const indecies = this.getIndeciesForRect(position, dimensions);
|
||||
let results = [];
|
||||
indecies.forEach((index) => {
|
||||
let res = this.nodes[index].find(position, dimensions);
|
||||
res.forEach((obj) => results.push(obj));
|
||||
});
|
||||
return results;
|
||||
}
|
||||
split() {
|
||||
const halfWidth = this.dimensions.x / 2;
|
||||
const halfHeight = this.dimensions.y / 2;
|
||||
const halfDepth = this.dimensions.z / 2;
|
||||
this.nodes[Direction.AboveUpperLeft] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.AboveUpperRight] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.AboveLowerRight] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.AboveLowerLeft] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z + halfDepth
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.BelowUpperLeft] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.BelowUpperRight] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.BelowLowerRight] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x + halfWidth,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.nodes[Direction.BelowLowerLeft] = new OctTreeNode(new Vec3({
|
||||
x: this.position.x,
|
||||
y: this.position.y + halfHeight,
|
||||
z: this.position.z
|
||||
}), new Vec3({
|
||||
x: halfWidth,
|
||||
y: halfHeight,
|
||||
z: halfDepth
|
||||
}), this.maxLevels, this.maxObjects);
|
||||
this.distributeObjectsToNodes();
|
||||
}
|
||||
distributeObjectsToNodes() {
|
||||
if (this.nodes.length < 8) {
|
||||
this.split();
|
||||
return;
|
||||
}
|
||||
this.objects.forEach((obj) => {
|
||||
const direction = this.getIndex(obj.position.x, obj.position.y, obj.position.z);
|
||||
this.nodes[direction].insert(obj);
|
||||
});
|
||||
this.objects = [];
|
||||
}
|
||||
getIndex(x, y, z) {
|
||||
if (this.nodes.length === 0) {
|
||||
return Direction.Here;
|
||||
}
|
||||
const halfWidth = this.dimensions.x / 2;
|
||||
const halfHeight = this.dimensions.y / 2;
|
||||
const halfDepth = this.dimensions.z / 2;
|
||||
const isBelow = (z < this.position.z + halfDepth);
|
||||
const isLeft = (x < this.position.x + halfWidth);
|
||||
const isUpper = (y > this.position.y + halfHeight);
|
||||
if (isBelow) {
|
||||
if (isLeft) {
|
||||
if (isUpper)
|
||||
return Direction.AboveUpperLeft;
|
||||
else
|
||||
return Direction.AboveLowerLeft;
|
||||
}
|
||||
else {
|
||||
if (isUpper)
|
||||
return Direction.AboveUpperRight;
|
||||
else
|
||||
return Direction.AboveLowerRight;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isLeft) {
|
||||
if (isUpper)
|
||||
return Direction.BelowUpperLeft;
|
||||
else
|
||||
return Direction.BelowLowerLeft;
|
||||
}
|
||||
else {
|
||||
if (isUpper)
|
||||
return Direction.BelowUpperRight;
|
||||
else
|
||||
return Direction.BelowLowerRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
getIndeciesForRect(position, dimensions) {
|
||||
let indecies = new Set();
|
||||
indecies.add(this.getIndex(position.x, position.y, position.z));
|
||||
indecies.add(this.getIndex(position.x + dimensions.x, position.y + dimensions.y, position.z + dimensions.z));
|
||||
return indecies;
|
||||
}
|
||||
}
|
||||
var Direction;
|
||||
(function (Direction) {
|
||||
Direction[Direction["AboveUpperLeft"] = 0] = "AboveUpperLeft";
|
||||
Direction[Direction["AboveUpperRight"] = 1] = "AboveUpperRight";
|
||||
Direction[Direction["AboveLowerRight"] = 2] = "AboveLowerRight";
|
||||
Direction[Direction["AboveLowerLeft"] = 3] = "AboveLowerLeft";
|
||||
Direction[Direction["BelowUpperLeft"] = 4] = "BelowUpperLeft";
|
||||
Direction[Direction["BelowUpperRight"] = 5] = "BelowUpperRight";
|
||||
Direction[Direction["BelowLowerRight"] = 6] = "BelowLowerRight";
|
||||
Direction[Direction["BelowLowerLeft"] = 7] = "BelowLowerLeft";
|
||||
Direction[Direction["Here"] = 8] = "Here";
|
||||
})(Direction || (Direction = {}));
|
0
framework/physics/quadtree.d.ts
vendored
Normal file
0
framework/physics/quadtree.d.ts
vendored
Normal file
0
framework/physics/quadtree.js
Normal file
0
framework/physics/quadtree.js
Normal file
13
framework/physics/vec3.d.ts
vendored
Normal file
13
framework/physics/vec3.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export declare class Vec3 {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
constructor(values?: {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
});
|
||||
add(vector: Vec3): void;
|
||||
multiply(vector: Vec3): void;
|
||||
clone(): Vec3;
|
||||
}
|
28
framework/physics/vec3.js
Normal file
28
framework/physics/vec3.js
Normal file
@@ -0,0 +1,28 @@
|
||||
export class Vec3 {
|
||||
constructor(values = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}) {
|
||||
this.x = values.x;
|
||||
this.y = values.y;
|
||||
this.z = values.z;
|
||||
}
|
||||
add(vector) {
|
||||
this.x += vector.x;
|
||||
this.y += vector.y;
|
||||
this.z += vector.z;
|
||||
}
|
||||
multiply(vector) {
|
||||
this.x *= vector.x;
|
||||
this.y *= vector.y;
|
||||
this.z *= vector.z;
|
||||
}
|
||||
clone() {
|
||||
return new Vec3({
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
z: this.z
|
||||
});
|
||||
}
|
||||
}
|
23
framework/physics/world.d.ts
vendored
Normal file
23
framework/physics/world.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Octree } from './octree';
|
||||
import { EventBus } from '../event-bus';
|
||||
import { PhysicsObject } from './object';
|
||||
import { Vec3 } from './vec3';
|
||||
export declare class World extends EventBus {
|
||||
objects: PhysicsObject[];
|
||||
gravity: Vec3;
|
||||
dimensions: Vec3;
|
||||
octreeOptions: OctreeOptions;
|
||||
constructor(dimensions: Vec3, octreeOptions: OctreeOptions);
|
||||
setGravity(grav: Vec3): void;
|
||||
addObject(obj: PhysicsObject): void;
|
||||
removeObject(obj: PhysicsObject): void;
|
||||
step(dt: number): void;
|
||||
checkCollisions(obj: PhysicsObject, octree: Octree): void;
|
||||
}
|
||||
interface OctreeOptions {
|
||||
position: Vec3;
|
||||
dimensions: Vec3;
|
||||
maxObjects: number;
|
||||
maxLevels: number;
|
||||
}
|
||||
export {};
|
54
framework/physics/world.js
Normal file
54
framework/physics/world.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Octree } from './octree';
|
||||
import { EventBus } from '../event-bus';
|
||||
import { Vec3 } from './vec3';
|
||||
import { AABB } from './aabb';
|
||||
export class World extends EventBus {
|
||||
constructor(dimensions, octreeOptions) {
|
||||
super();
|
||||
if (!octreeOptions) {
|
||||
this.octreeOptions = {
|
||||
position: new Vec3({ x: 0, y: 0, z: 0 }),
|
||||
dimensions: new Vec3(this.dimensions),
|
||||
maxLevels: 50,
|
||||
maxObjects: 50
|
||||
};
|
||||
}
|
||||
else {
|
||||
this.octreeOptions = octreeOptions;
|
||||
}
|
||||
this.dimensions = dimensions;
|
||||
this.objects = [];
|
||||
}
|
||||
setGravity(grav) {
|
||||
this.gravity = grav;
|
||||
}
|
||||
addObject(obj) {
|
||||
this.objects.push(obj);
|
||||
}
|
||||
removeObject(obj) {
|
||||
this.objects = this.objects.filter((val) => val !== obj);
|
||||
}
|
||||
step(dt) {
|
||||
const octree = new Octree(this.octreeOptions.dimensions, this.octreeOptions.maxObjects, this.octreeOptions.maxLevels);
|
||||
this.objects.forEach((obj) => octree.insert(obj));
|
||||
this.objects.forEach((obj) => {
|
||||
let velocity = obj.velocity.clone();
|
||||
velocity.multiply(new Vec3({ x: dt, y: dt, z: dt }));
|
||||
let gravity = this.gravity.clone();
|
||||
gravity.multiply(new Vec3({ x: dt, y: dt, z: dt }));
|
||||
obj.position.add(velocity);
|
||||
if (obj.affectedByGravity) {
|
||||
obj.velocity.add(gravity);
|
||||
}
|
||||
this.checkCollisions(obj, octree);
|
||||
});
|
||||
}
|
||||
checkCollisions(obj, octree) {
|
||||
const potentialCandidates = octree.find(obj.position, obj.dimensions);
|
||||
potentialCandidates.forEach((candidate) => {
|
||||
if (AABB(obj, candidate)) {
|
||||
this.emit('collision', [obj, candidate]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user