Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lesson 035 - Scene Graph / Transformation Hierarchy
- Loading branch information
1 parent
5a29e60
commit f70faf5
Showing
9 changed files
with
3,361 additions
and
1 deletion.
There are no files selected for viewing
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,7 @@ | ||
# Fun with WebGL 2.0 - 035 - Scene Graph / Transformation Hierarchy | ||
**Description**: | ||
Today we finally to get implement our transform parent-child relationships. This allows all our transformations to cascade from parent to child in a way to create specific effects very easily. We also get to use our transform object as an empty/folder/container/groups to create a single point to apply a transformation to a group of renderables. | ||
|
||
### Links | ||
* [Lesson on Youtube](https://youtu.be/1QDsBgkahY8) | ||
* [Youtube Series PlayList](https://www.youtube.com/playlist?list=PLMinhigDWz6emRKVkVIEAaePW7vtIkaIF) |
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,142 @@ | ||
Fungi.KBMCtrl = class{ | ||
constructor(){ | ||
this.canvas = Fungi.gl.canvas; | ||
this.initX = 0; | ||
this.initY = 0; | ||
this.prevX = 0; | ||
this.prevY = 0; | ||
this._boundMouseMove = this.onMouseMove.bind(this); | ||
|
||
var box = this.canvas.getBoundingClientRect(); | ||
this.offsetX = box.left; | ||
this.offsetY = box.top; | ||
|
||
this.canvas.addEventListener("mousedown",this.onMouseDown.bind(this)); | ||
this.canvas.addEventListener("mouseup",this.onMouseUp.bind(this)); | ||
//this.canvas.addEventListener("mouseout",this.onMouseUp.bind(this)); | ||
this.canvas.addEventListener("mousewheel", this.onMouseWheel.bind(this)); | ||
|
||
document.addEventListener("keydown",this.onKeyDown.bind(this)); | ||
document.addEventListener("keyup",this.onKeyUp.bind(this)); | ||
|
||
this.onDownOverride = null; //Optional, Allow the ability to swop event handlers or do whatever else before the evtHandlers do their job | ||
this._activeHandler = null; //Handlers are like state machines, swop functionality when needed | ||
this._handlers = {}; | ||
} | ||
|
||
switchHandler(name,data){ | ||
if(this._activeHandler.onDeactivate) this._activeHandler.onDeactivate(); | ||
this._activeHandler = this._handlers[name]; | ||
if(this._activeHandler.onActive) this._activeHandler.onActive(data); | ||
return this; | ||
} | ||
|
||
addHandler(name,h,active){ | ||
this._handlers[name] = h; | ||
if(active == true) this._activeHandler = h; | ||
return this; | ||
} | ||
|
||
setDownOverride(d){ this.onDownOverride = d; return this; } | ||
|
||
onMouseWheel(e){ | ||
if(!this._activeHandler.onMouseWheel) return; | ||
|
||
e.preventDefault(); e.stopPropagation(); | ||
|
||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); //Try to map wheel movement to a number between -1 and 1 | ||
this._activeHandler.onMouseWheel(e,this,delta); | ||
} | ||
|
||
onMouseDown(e){ | ||
e.preventDefault(); e.stopPropagation(); | ||
|
||
this.initX = this.prevX = e.pageX - this.offsetX; | ||
this.initY = this.prevY = e.pageY - this.offsetY; | ||
|
||
if(this.onDownOverride != null) this.onDownOverride(e,this,this.initX,this.initY); | ||
if(this._activeHandler.onMouseDown) this._activeHandler.onMouseDown(e,this,this.initX,this.initY); | ||
|
||
this.canvas.addEventListener("mousemove",this._boundMouseMove); | ||
} | ||
|
||
onMouseMove(e){ | ||
e.preventDefault(); e.stopPropagation(); | ||
|
||
var x = e.pageX - this.offsetX, //Get X,y where the canvas's position is origin. | ||
y = e.pageY - this.offsetY, | ||
dx = x - this.prevX, //Difference since last mouse move | ||
dy = y - this.prevY; | ||
|
||
if(this._activeHandler.onMouseMove) this._activeHandler.onMouseMove(e,this,x,y,dx,dy); | ||
this.prevX = x; | ||
this.prevY = y; | ||
} | ||
|
||
onMouseUp(e){ | ||
e.preventDefault(); e.stopPropagation(); | ||
|
||
var x = e.pageX - this.offsetX, //Get X,y where the canvas's position is origin. | ||
y = e.pageY - this.offsetY, | ||
dx = x - this.prevX, //Difference since last mouse move | ||
dy = y - this.prevY; | ||
|
||
this.canvas.removeEventListener("mousemove",this._boundMouseMove); | ||
if(this._activeHandler.onMouseUp) this._activeHandler.onMouseUp(e,this,x,y,dx,dy); | ||
} | ||
|
||
////console.log(e.key,e.keyCode,e.shiftKey,e.ctrlKey); | ||
onKeyDown(e){ | ||
if(this._activeHandler.onKeyDown){ | ||
e.preventDefault(); e.stopPropagation(); | ||
this._activeHandler.onKeyDown(e,this,e.keyCode); | ||
} | ||
} | ||
|
||
onKeyUp(e){ | ||
if(this._activeHandler.onKeyUp){ | ||
this._activeHandler.onKeyUp(e,this,e.keyCode); | ||
e.preventDefault(); e.stopPropagation(); | ||
} | ||
} | ||
} | ||
|
||
Fungi.KBMCtrl_Viewport = class{ | ||
constructor(camera){ | ||
var w = Fungi.gl.fWidth, h = Fungi.gl.fHeight; | ||
this.camera = camera; | ||
|
||
this.rotRate = -500; //How fast to rotate, degrees per dragging delta | ||
this.panRate = 5; //How fast to pan, max unit per dragging delta | ||
this.zoomRate = 200; //How fast to zoom or can be viewed as forward/backward movement | ||
|
||
this.yRotRate = this.rotRate / w * Math.PI/180; | ||
this.xRotRate = this.rotRate / h * Math.PI/180; | ||
this.xPanRate = this.panRate / w; | ||
this.yPanRate = this.panRate / h; | ||
this.zPanRate = this.zoomRate / h; | ||
} | ||
|
||
onMouseWheel(e,ctrl,delta){ this.camera.position.z += delta * this.zPanRate; } | ||
onMouseMove(e,ctrl,x,y,dx,dy){ | ||
//When shift is being helt down, we pan around else we rotate. | ||
if(!e.shiftKey){ | ||
this.camera.euler.y += dx * this.yRotRate; | ||
this.camera.euler.x += dy * this.xRotRate; | ||
}else{ | ||
this.camera.position.x += -dx * this.xPanRate; | ||
this.camera.position.y += dy * this.yPanRate; | ||
} | ||
} | ||
|
||
onKeyDown(e,ctrl,keyCode){ | ||
switch(keyCode){ | ||
case 87: this.camera.position.z -= 2 * this.zPanRate; break; //W | ||
case 83: this.camera.position.z += 2 * this.zPanRate; break; //S | ||
case 65: this.camera.position.x -= 50 * this.xPanRate; break; //A | ||
case 68: this.camera.position.x += 50 * this.xPanRate; break; //D | ||
case 81: this.camera.euler.y += 10 * this.yRotRate; break; //Q | ||
case 69: this.camera.euler.y -= 10 * this.yRotRate; break; //E | ||
} | ||
} | ||
} |
Oops, something went wrong.