Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a68c600
commit 3458cb2
Showing
46 changed files
with
6,803 additions
and
0 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import gl from "./gl.js"; | ||
import CameraOrbit from "./cameras/Orbit.js"; | ||
import GridFloor from "./primitives/GridFloor.js"; | ||
import Renderer from "./util/Renderer.js"; | ||
import RenderLoop from "./util/RenderLoop.js"; | ||
import VDebug from "./entities/VisualDebugger.js"; | ||
import {KBMCtrl, KBMCtrl_Viewport} from "./util/KBMCtrl.js" | ||
|
||
export default{ | ||
render :Renderer, //Main Render Function | ||
renderLoop :null, //Render loop | ||
lblFPS :null, //Html Element reference to a tag to update text of FPS | ||
|
||
mainCamera :null, //Main camera for the scene | ||
ctrlCamera :null, //Keyboard and Mouse controls for the camera | ||
|
||
debugLine :null, //Renderable used to help debug data or models | ||
debugPoint :null, //Same but with points. | ||
|
||
gridFloor :null, //Just a reference to the renderable for the grid floor. | ||
scene :[], //Array that holds the heirarchy of transforms / renderables. | ||
|
||
deltaTime :0, | ||
sinceStart :0, | ||
|
||
//Begin the GL Context | ||
init:function(){ gl.set("FungiCanvas"); return this; }, | ||
|
||
//Build all the main objects needed to get a scene up and running | ||
ready:function(renderHandler,opt){ | ||
this.mainCamera = new CameraOrbit().setPosition(0,0.5,4).setEulerDegrees(-15,10,0); | ||
this.ctrlCamera = new KBMCtrl().addHandler("camera",new KBMCtrl_Viewport(this.mainCamera),true,true); | ||
|
||
this.renderLoop = new RenderLoop(renderHandler); | ||
this.lblFPS = document.getElementById("lblFPS"); | ||
setInterval(function(){ this.lblFPS.innerHTML = this.renderLoop.fps; }.bind(this),200); | ||
|
||
this.gridFloor = GridFloor(); | ||
this.scene.push(this.gridFloor); | ||
|
||
//Setup Features | ||
if(opt){ | ||
if(opt & 1 == 1) this.scene.push( this.debugLine = new VDebug() ); //DEBUG LINE RENDERER | ||
if(opt & 2 == 2) this.scene.push( this.debugPoint = new VDebug().drawPoints() ); //DEBUG POINT RENDERER | ||
} | ||
}, | ||
|
||
//Get a frame ready to be rendered. | ||
update:function(){ | ||
this.mainCamera.update(); | ||
|
||
gl.UBOTransform.update( | ||
"matCameraView",this.mainCamera.invertedLocalMatrix, | ||
"posCamera",this.mainCamera.position, | ||
"fTime",new Float32Array( [this.sinceStart] ) | ||
); | ||
|
||
gl.clear(); | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import Vec3 from "./maths/Vec3.js"; | ||
import Mat3 from "./maths/Mat3.js"; | ||
import Mat4 from "./maths/Mat4.js"; | ||
import Quat from "./maths/Quat.js"; | ||
import DualQuat from "./maths/DualQuat.js"; | ||
|
||
const DEG2RAD = Math.PI/180; | ||
const RAD2DEG = 180/Math.PI; | ||
|
||
//Normalize x value to x range, then normalize to lerp the z range. | ||
function map(x, xMin,xMax, zMin,zMax){ return (x - xMin) / (xMax - xMin) * (zMax-zMin) + zMin; } | ||
|
||
function clamp(v,min,max){ return Math.max(min,Math.min(max,v)); } | ||
|
||
function smoothStep(edge1, edge2, val){ //https://en.wikipedia.org/wiki/Smoothstep | ||
var x = Math.max(0, Math.min(1, (val-edge1)/(edge2-edge1))); | ||
return x*x*(3-2*x); | ||
} | ||
|
||
//Get a number between A and B from a normalized number. | ||
function lerp(a,b,t){ return a + t * (b-a); } | ||
|
||
//From a point in space, closest spot to a 2D line | ||
function closestPointToLine2D(x0,y0,x1,y1,px,py){ | ||
var dx = x1 - x0, | ||
dy = y1 - y0, | ||
t = ((px-x0)*dx + (py-y0)*dy) / (dx*dx+dy*dy), | ||
x = x0 + (dx * t), //Util.lerp(x0, x1, t), | ||
y = y0 + (dy * t); //Util.lerp(y0, y1, t); | ||
return [x,y] | ||
} | ||
|
||
//From a point in space, closest spot to a 3D line | ||
function closestPointToLine3D(a,b,p,out){ | ||
if(out == undefined) out = new Vec3(); | ||
var dx = b.x - a.x, | ||
dy = b.y - a.y, | ||
dz = a.z - a.z, | ||
t = ((p.x-a.x)*dx + (p.y-a.y)*dy + (p.z-a.z)*dz) / (dx*dx+dy*dy+dz*dz), | ||
x = a.x + (dx * t), | ||
y = a.y + (dy * t), | ||
z = a.z + (dz * t); | ||
return out.set(x,y,z); | ||
} | ||
|
||
//Return back the two points that are closes on two infinite lines | ||
//http://geomalgorithms.com/a07-_distance.html | ||
function closestpoint_2Lines(A0,A1,B0,B1){ | ||
var u = A1.clone().sub(A0), | ||
v = B1.clone().sub(B0), | ||
w = A0.clone().sub(B0), | ||
a = Vec3.dot(u,u), // always >= 0 | ||
b = Vec3.dot(u,v), | ||
c = Vec3.dot(v,v), // always >= 0 | ||
d = Vec3.dot(u,w), | ||
e = Vec3.dot(v,w), | ||
D = a*c - b*b, // always >= 0 | ||
tU, tV; | ||
//compute the line parameters of the two closest points | ||
if(D < 0.000001){ // the lines are almost parallel | ||
tU = 0.0; | ||
tV = (b>c ? d/b : e/c); // use the largest denominator | ||
}else{ | ||
tU = (b*e - c*d) / D; | ||
tV = (a*e - b*d) / D; | ||
} | ||
|
||
//Calc Length | ||
//Vector vLen = w + (uT * u) - (vT * v); // = L1(sc) - L2(tc) | ||
//Float len = sqrt( dot(vLen,vLen) ); | ||
|
||
return [ u.scale(tU).add(A0), v.scale(tV).add(B0) ]; | ||
} | ||
|
||
//Return back the two points that are the closests but bound by the limit of two segments | ||
//http://geomalgorithms.com/a07-_distance.html | ||
function closestPointS_2Segments(A0,A1,B0,B1){ | ||
var u = A1.clone().sub(A0), | ||
v = B1.clone().sub(B0), | ||
w = A0.clone().sub(B0), | ||
a = Vec3.dot(u,u), // always >= 0 | ||
b = Vec3.dot(u,v), | ||
c = Vec3.dot(v,v), // always >= 0 | ||
d = Vec3.dot(u,w), | ||
e = Vec3.dot(v,w), | ||
D = a*c - b*b, // always >= 0 | ||
sc, sN, sD = D, // sc = sN / sD, default sD = D >= 0 | ||
tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0 | ||
|
||
// compute the line parameters of the two closest points | ||
if(D < 0.000001){ // the lines are almost parallel | ||
sN = 0.0; // force using point P0 on segment S1 | ||
sD = 1.0; // to prevent possible division by 0.0 later | ||
tN = e; | ||
tD = c; | ||
}else{ // get the closest points on the infinite lines | ||
sN = (b*e - c*d); | ||
tN = (a*e - b*d); | ||
if(sN < 0.0){ // sc < 0 => the s=0 edge is visible | ||
sN = 0.0; | ||
tN = e; | ||
tD = c; | ||
}else if (sN > sD){ // sc > 1 => the s=1 edge is visible | ||
sN = sD; | ||
tN = e + b; | ||
tD = c; | ||
} | ||
} | ||
|
||
if (tN < 0.0){ // tc < 0 => the t=0 edge is visible | ||
tN = 0.0; | ||
// recompute sc for this edge | ||
if (-d < 0.0) sN = 0.0; | ||
else if (-d > a) sN = sD; | ||
else{ | ||
sN = -d; | ||
sD = a; | ||
} | ||
}else if(tN > tD){ // tc > 1 => the t=1 edge is visible | ||
tN = tD; | ||
// recompute sc for this edge | ||
if((-d + b) < 0.0) sN = 0; | ||
else if ((-d + b) > a) sN = sD; | ||
else{ | ||
sN = (-d + b); | ||
sD = a; | ||
} | ||
} | ||
|
||
// finally do the division to get sc and tc | ||
sc = (Math.abs(sN) < 0.000001 ? 0.0 : sN / sD); | ||
tc = (Math.abs(tN) < 0.000001 ? 0.0 : tN / tD); | ||
|
||
// get the difference of the two closest points | ||
//Vector dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) | ||
|
||
return [ u.scale(sc).add(A0), v.scale(tc).add(B0) ]; | ||
} | ||
|
||
|
||
export default { DEG2RAD:DEG2RAD, RAD2DEG:RAD2DEG, | ||
map:map, | ||
clamp:clamp, | ||
smoothStep:smoothStep, | ||
closestPointToLine2D:closestPointToLine2D, | ||
closestPointToLine3D:closestPointToLine3D, | ||
closestpoint_2Lines:closestpoint_2Lines, | ||
closestPointS_2Segments:closestPointS_2Segments, | ||
} | ||
|
||
export { Vec3, Mat3, Mat4, Quat, DualQuat, DEG2RAD, RAD2DEG } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import gl from "../gl.js"; | ||
import fungi from "../fungi.js"; | ||
import Transform from "../entities/Transform.js"; | ||
import {Vec3, Mat4, Quat, DEG2RAD} from "../Maths.js"; | ||
|
||
class Orbit extends Transform{ | ||
constructor(fov,near,far){ | ||
super(); | ||
//Setup the projection and invert matrices | ||
this.projectionMatrix = new Float32Array(16); | ||
this.invertedProjectionMatrix = new Float32Array(16); | ||
this.invertedLocalMatrix = new Float32Array(16); | ||
|
||
var ratio = gl.ctx.canvas.width / gl.ctx.canvas.height; | ||
Mat4.perspective(this.projectionMatrix, fov || 45, ratio, near || 0.1, far || 100.0); | ||
Mat4.invert(this.invertedProjectionMatrix, this.projectionMatrix); //Save Inverted version for Ray Casting. | ||
|
||
gl.UBOTransform.update("matProjection",this.projectionMatrix); //Initialize The Transform UBO. | ||
|
||
//Orbit Camera will control things based on euler, its cheating but not ready for quaternions | ||
this.euler = new Vec3(); | ||
} | ||
|
||
//Override how this transfer creates the localMatrix : Call Update, not this function in render loop. | ||
updateMatrix(){ | ||
//Only Update the Matrix if its needed. | ||
//if(!this.position.isModified && !this.rotation.isModified && !this.euler.isModified) return this.localMatrix; | ||
|
||
Quat.setFromEuler(this.rotation,this.euler.x,this.euler.y,this.euler.z,"YXZ"); | ||
Mat4.fromQuaternion(this.localMatrix,this.rotation); | ||
this.localMatrix.resetTranslation().translate(this.position); | ||
|
||
//Set the modified indicator to false on all the transforms. | ||
this.position.isModified = false; | ||
this.rotation.isModified = false; | ||
this.euler.isModified = false; | ||
return this.localMatrix; | ||
} | ||
|
||
//Update the Matrices and UBO. | ||
update(){ | ||
if(this.position.isModified || this.scale.isModified || this.euler.isModified){ | ||
this.updateMatrix(); | ||
Mat4.invert(this.invertedLocalMatrix,this.localMatrix); | ||
} | ||
} | ||
|
||
setEulerDegrees(x,y,z){ this.euler.set(x * DEG2RAD,y * DEG2RAD,z * DEG2RAD); return this; } | ||
|
||
worldToScreen(vAry){ | ||
var mat = new Float32Array(16), // Matrix4 Holder | ||
p = [0,0,0,0], // Vec4 | ||
rtn = []; // List of vec2 results | ||
|
||
//Move Points from WorldSpace to -> View Space (View Matrix) -> ClipSpace (ProjMatrix) | ||
Mat4.mult(mat,this.projectionMatrix,this.invertedLocalMatrix); | ||
|
||
for(var i=0; i < vAry.length; i++){ | ||
Mat4.transformVec3(p, vAry[i], mat); | ||
|
||
//Move from Clip Space to NDC Space (Normalized Device Coordinate Space) (-1 to 1 opengl viewport) | ||
if(p[3] != 0){ //only if W is not zero, | ||
p[0] = p[0] / p[3]; | ||
p[1] = p[1] / p[3]; | ||
} | ||
|
||
//Then finally move the points to Screen Space | ||
//Map points from -1 to 1 range into 0 to 1 range, Then multiple by canvas size | ||
rtn.push( // Replaced /2 with *0.5 | ||
( p[0] + 1) * 0.5 * gl.width, | ||
(-p[1] + 1) * 0.5 * gl.height | ||
); | ||
} | ||
|
||
if(vAry.length == 1) return rtn[0]; //Just return the one point | ||
return rtn; //Return all the points | ||
} | ||
} | ||
|
||
export default Orbit; |
Oops, something went wrong.