Published
Edited
Dec 10, 2020
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
if(TwoDThreeD(scene) == 0){
const camera = createCamera(regl, cameraType[options.cam])

// mouse tracking (Scrapped Idea, Causes Glitching)
//myCanvas.onmousemove = (e) => {
//mutable mousePos = {x: e.offsetX, y: e.offsetY};
//}


const deltaTime = 0.017
var transform;
var rotation;
var scale;
const div = html`<div>`;
var energy;
// Create Objects
var objects = [];
for(var i = 0; i < menuarea.objectNum; i++)
{
var temp = createObject(i);
objects.push(temp);
}

// Render object on Click, Plays sound unless muted
if (options.cam == 0) {
myCanvas.onclick = () => {
if (options.mute == "No") {
doorbell.play();
}
var temp = createObject(i);
objects.push(temp);
i++;
}
}
// Run Update Loop
const frame = regl.frame(() => {
energy = 0;
camera((state) => {
// regl.clear({color: [0, 0, 0, 1]});
renderSkybox();

objects.forEach(function(object)
{
updatePosition(object);
collisionDetection(objects, object.id);

if(object.shape == "sphere")
renderSphere({transform: transMat(object.position[0], object.position[1], object.position[2]),
scale: scaleMat(object.scale[0], object.scale[1], object.scale[2]),
rotation: rotationMat(object.rotation[0], object.rotation[1], object.rotation[2])
});
else if(object.shape == "cube") var temp;
else if(object.shape == "AABB") var temp;
//calculate energy of system
energy += vec3.dot(object.velocity,object.velocity) * object.mass;
div.textContent = "Kinetic Energy Of System = " + Math.round(energy * 100000)/100000 + "J";
});
let tempScale = 0;
if(TwoDThreeD(scene) == 0)
tempScale = menuarea.boundingSize;
renderBounds({scale: tempScale+1});
})
})
invalidation.then(() => frame.cancel());
return div;
} else if(TwoDThreeD(scene) == 1){
//2D render loop
let allObjects = new Array(menuarea.Number);
// let stick = createCube(0);
// allObjects.push(stick);

for (let i = 0; i < allObjects.length; i++)
{
allObjects[i] = createBall(i);
}

const frame = regl.frame(() => {

regl.clear({color: [0, 0.1, 0.1, 1]});

for (let i = 0; i < allObjects.length; i++)
{
vec3.add(allObjects[i].velocity, allObjects[i].velocity, allObjects[i].acceloration);
vec3.add(allObjects[i].position, allObjects[i].position, allObjects[i].velocity);

collisionDetection2D(allObjects, allObjects[i].id);

renderBall({model: modelMatrix(allObjects[i].position[0], allObjects[i].position[1],
allObjects[i].rotation[2]), color: allObjects[i].color});
};

})
invalidation.then(() => frame.cancel());
return `2D Rendering`;
} else if(TwoDThreeD(scene) == 2) {
// Arbitrary Mesh
const camera = createCamera(regl, {
center: [0, 0, 0],
distance: menuarea.boundingSize * 5,
noScroll: true,
fovy: toRadian(60),
damping: 0,
near: 2.5,
far: menuarea.boundingSize * 10
})

const deltaTime = 0.017
var transform;
var rotation;
var scale;
const div = html`<div>`;
var energy;

// Create Objects
var objects = [];
for(var i = 0; i < menuarea.objectNum; i++)
{
var temp = createObjectAABB(i);
temp.scale = vec3.fromValues(temp.mass,temp.mass,temp.mass),
objects.push(temp);
}

var scaleV = vec3.copy([], get_AABB_Dimensions(cow));
//var scaleV = vec3.fromValues([], 1, 1, 1);

// Run Update Loop
const frame = regl.frame(() => {
energy = 0;
camera((state) => {
regl.clear({color: [0, 0, 0, 1]});

objects.forEach(function(object)
{
updatePosition(object);
collisionDetectionAABB(objects, object.id);

if(object.shape == "cow")
{
renderSphereAABB({transform: transMatAABB(object.position[0], object.position[1], object.position[2]),
scale: scaleMatAABB(object.scale[0], object.scale[1], object.scale[2]),
rotation: rotationMatAABB(object.rotation[0], object.rotation[1], object.rotation[2])
});
renderAABB({transform: transMatAABB(object.position[0], object.position[1], object.position[2]),
scale: scaleMatAABB(scaleV[0]/2, scaleV[1]/2, scaleV[2]/2),
rotation: rotationMatAABB(object.rotation[0], object.rotation[1], object.rotation[2])
});
console.log(object.scale);
console.log(scaleV);
}
else if(object.shape == "cube") var temp;
else if(object.shape == "AABB") var temp;

//calculate energy of system

energy += vec3.squaredLength(object.velocity);
div.textContent = "Kinetic Energy Of System = " + Math.round(energy * 100000)/100000 + "J";
});
renderBounds({scale: menuarea.boundingSize});
})
})
invalidation.then(() => frame.cancel());

return `Arbitrary Mesh`
} else if(TwoDThreeD(scene) == 3) {
// Octree
const camera = createCamera(regl, {
center: [0, 0, 0],
distance: menuarea.boundingSize * 5,
noScroll: true,
fovy: convert(60),
damping: 0,
near: 2.5,
far: menuarea.boundingSize * 10
})

const deltaTime = 0.017
var transform;
var rotation;
var scale;

// Create Objects
var objects = [];
for(var i = 0; i < menuarea.objectNum; i++)
{
var temp = createObjectOc(i);
objects.push(temp);
}

// Run Update Loop
const frame = regl.frame(() => {
camera((state) => {
renderSkybox();

// Update and draw spheres.
objects.forEach(function(object) {
updatePosition(object);

if(object.shape == "sphere")
renderSphereOc({transform: transMat(object.position[0], object.position[1], object.position[2])});
else if(object.shape == "cube") var temp;
else if(object.shape == "AABB") var temp;
});

// Check whether to use optimization.
if (menuarea.optimizedMode.includes("op")) {
// Construct octree.
let tree = createNode(menuarea.boundingSize + 1.0, [0.0, 0.0, 0.0]);
for (var object of objects) {
if(!insert(object, tree)){
tree.objects.push(object);
}
}

// Use octree to check for collisions.
octreeCollisionOc(tree);

// Draw tree.
if (menuarea.optimizedMode.includes("show")) {
drawTree(tree);
}
} else {
// Use brute force method.
for (let i=0; i<objects.length; i++) {
collisionDetectionOc(objects.slice(i + 1), objects[i])
}
}

renderBoundsOc({scale: menuarea.boundingSize, transform: transMat(0.0, 0.0, 0.0)});
})
})
invalidation.then(() => frame.cancel());
return "Octree"
} else {
// Rotation
const camera = createCamera(regl, {
center: [0, 0, 0],
distance: boundingSize * 5,
noScroll: true,
fovy: toRadian(60),
damping: 0,
near: 2.5,
far: boundingSize * 10
})
const deltaTime = 0.017
var transform;
var rotation;
var scale;
const div = html`<div>`;
var energy;
var timer = 0;
// Create Objects
var objects = [];
var temp = createOBB(0);
//temp.scale = vec3.fromValues(temp.mass,temp.mass,temp.mass),
objects.push(temp);
temp = createSphere(1);
objects.push(temp);
temp = createSphere(2);
objects.push(temp);
temp = createSphere(3);
objects.push(temp);
temp = createSphere(4);
objects.push(temp);
temp = createSphere(5);
objects.push(temp);
// Run Update Loop
const frame = regl.frame(() => {
energy = 0;
camera((state) => {
regl.clear({color: [0, 0, 0, 1]});
objects.forEach(function(object)
{
updatePosition(object);
collisionDetection(objects, object.id);
if(object.shape == "sphere")
{
renderSphereOc({transform: transMat(object.position[0], object.position[1], object.position[2])});
}
else if(object.shape == "cube") var temp;
else if(object.shape == "OBB")
{
updateRotation(object);
renderOBB({transform: transMat(object.position[0], object.position[1], object.position[2]),
scale: scaleMat(object.scale[0], object.scale[1], object.scale[2]),
rotation: rotationMat(object.rotation[0], object.rotation[1], object.rotation[2])
});
}
//calculate energy of system
energy += vec3.squaredLength(object.velocity);
div.textContent = "Kinetic Energy Of System = " + Math.round(energy * 100000)/100000 + "J";
});
renderBounds({scale: menuarea.boundingSize});
})
})
invalidation.then(() => frame.cancel());
return div
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md `## Project Overview
The REGL 3D Object Collider project aimed to implement a physics simulator in Observable using REGL API. The software models momentum-conserving elastic collisions and gravity within a static bounding cube. The notebook also sports a minor 2D collider to demonstrate two-dimensional collision physics in REGL.

The 3D Object Collider allows for user control of a number of variables within the simulation, such as object count, object speed, object model, object texture, bounding box size, and more. Users can also modify scene gravity and object mass to add greater depth to the simulation. The notebook comes preloaded with a number of example scenes to outline the collider’s functions.

Our 3D collisions are implemented with object radius checks in the case of spheres and axis-aligned bounding boxes on complex models. These bounding box collisions have been optimized with an octree data structure, the visualization of which can be enabled in the simulator options. Collisions are resolved using balanced classical physics equations that conserve the momentum of colliding objects.
`
Insert cell
md `## Refrences
http://www.r-5.org/files/books/computers/algo-list/realtime-3d/Christer_Ericson-Real-Time_Collision_Detection-EN.pdf

https://www.euclideanspace.com/physics/dynamics/collision/threed/index.htm

https://atmos.illinois.edu/courses/atmos100/userdocs/3Dcollisions.html
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
objectNum = ["1","12","12","5","10"]
Insert cell
mass = [1,1,1,1,7]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function rotationMat(x,y,z){
return mat4.multiply([], mat4.fromXRotation([], toRadian(x)), mat4.multiply([], mat4.fromXRotation([], toRadian(y)), mat4.fromXRotation([], toRadian(z))));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3_ = require("d3@5")
Insert cell
import {createNode, insert} from "@ctkerns/octree-data-structure"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md `# Rotation `
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more