New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Camera! #28
Closed
Closed
Camera! #28
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
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 |
---|---|---|
|
@@ -810,6 +810,8 @@ chesterGL.setupPerspective = function () { | |
} else { | ||
throw "Invalid projection: " + chesterGL.projection; | ||
} | ||
|
||
chesterGL.basePMatrix = chesterGL.pMatrix; | ||
}; | ||
|
||
/** | ||
|
@@ -822,11 +824,54 @@ chesterGL.setRunningScene = function (block) { | |
} | ||
}; | ||
|
||
/** | ||
* Sets the current camera. The scene will be rendered as if seen from a camera attached to the block. | ||
* @param {chesterGL.Block} A Block of type Camera, created thusly: new chesterGL.Block(null, chesterGL.Block.TYPE.CAMERA) | ||
*/ | ||
chesterGL.setCamera = function(block) { | ||
if (block.type == chesterGL.Block.TYPE['CAMERA']) { | ||
chesterGL.camera = block; | ||
} | ||
} | ||
|
||
/** | ||
* main draw function, will call the root block | ||
* @ignore | ||
*/ | ||
chesterGL.drawScene = function () { | ||
//Setup camera transformation | ||
var par = chesterGL.camera; | ||
var parents = []; | ||
// Work up the camera's chain of parents. This is somewhat inefficient, as they'll also get | ||
// transformed as part of rendering the scene, but it's worth having the ability to just | ||
// attach a camera to some block and have it follow the block, etc. | ||
while(par) { | ||
parents.push(par); | ||
par = par.parent; | ||
} | ||
|
||
// We go backwards so that we start at the root and finish with the camera. | ||
for(var i=parents.length-1; i >= 0; i--) { | ||
parents[i].updateTransform(); | ||
} | ||
|
||
// Invert and multiply onto the view transform. | ||
// this looks a little wonky when using a camera that is a child of a normal block | ||
// because we end up using the previous frame's transform for that block. | ||
// TODO: refactor Block.visit into separate update and transform steps so we can | ||
// use the current frame's transform here. This would also let us have multiple | ||
// cameras each with their own viewport in the main port, picture in picture style. | ||
chesterGL.pMatrix = goog.vec.Mat4.createFloat32(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. If you're doing this every frame, ideally you want to have a temp vector/matrix around just to reuse it and avoid creation every frame, that's more friendly with GC |
||
var camTransform = goog.vec.Mat4.createFloat32(); | ||
if(goog.vec.Mat4.invert(chesterGL.camera.mvMatrix, camTransform)) { | ||
goog.vec.Mat4.multMat(chesterGL.basePMatrix, camTransform, chesterGL.pMatrix); | ||
} | ||
else { | ||
if(console) console.log("Inverse of camera transform is undefined!"); | ||
} | ||
|
||
chesterGL.runningScene.isTransformDirty = true; | ||
|
||
var gl = undefined; | ||
if (chesterGL.webglMode) { | ||
gl = chesterGL.gl; | ||
|
@@ -1103,3 +1148,4 @@ goog.exportSymbol('chesterGL.togglePause', chesterGL.togglePause); | |
goog.exportSymbol('chesterGL.isPaused', chesterGL.isPaused); | ||
goog.exportSymbol('chesterGL.addMouseHandler', chesterGL.addMouseHandler); | ||
goog.exportSymbol('chesterGL.removeMouseHandler', chesterGL.removeMouseHandler); | ||
goog.exportSymbol('chesterGL.setCamera', chesterGL.setCamera); |
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,108 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link rel="stylesheet" type="text/css" href="test.css"/> | ||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> | ||
<!-- <script type="text/javascript" src="externals/webgl-debug.js"></script> --> | ||
<script type="text/javascript" src="chester.js"></script> | ||
<!-- audio!! --> | ||
<script type="text/javascript"> | ||
|
||
$(document).ready(function () { | ||
setupGame(); | ||
function setupGame() { | ||
chesterGL.settings['useGoogleAnalytics'] = true; | ||
chesterGL.setup("demo-canvas"); | ||
var size = chesterGL.viewportSize(); | ||
var oneDeg = Math.PI / 180.0; | ||
|
||
chesterGL.loadAsset("texture", "images/test.png"); | ||
chesterGL.loadAsset("texture", "images/star.png"); | ||
chesterGL.assetsLoaded("texture", function () { | ||
// $("#loading").html("Test Single Block"); | ||
// finish with the setup and run the game | ||
chesterGL.setupPerspective(); | ||
|
||
var sceneBlock = new chesterGL.Block(null, chesterGL.Block.TYPE['SCENE']); | ||
sceneBlock.title = "Test::Single Block"; | ||
chesterGL.setRunningScene(sceneBlock); | ||
|
||
// create a block | ||
var someBlock = new chesterGL.Block(); | ||
someBlock.setTexture("images/test.png") | ||
// someBlock.rotateBy(-45); | ||
someBlock.setPosition([size.width/2, size.height/2, 0]); | ||
|
||
var someBlock2 = new chesterGL.Block(); | ||
someBlock2.setTexture("images/star.png"); | ||
someBlock2.setPosition([60, 0, 0]); | ||
someBlock.addChild(someBlock2); | ||
|
||
sceneBlock.addChild(someBlock); | ||
|
||
|
||
var someBlock3 = new chesterGL.Block(); | ||
someBlock3.setTexture("images/star.png"); | ||
someBlock3.setPosition([30, 60, 0]); | ||
|
||
// === CAMERA EXAMPLE === | ||
// create a camera: | ||
var camera = new chesterGL.Block(null, chesterGL.Block.TYPE.CAMERA); | ||
// Misfeature: the camera's position is actually the location of the lower-left | ||
// corner of the viewport. So, if you want the camera's parent in the center, | ||
// you have to set the offset yourself. This should be fixed in a later update. | ||
camera.setPosition([-200, -200, 220]); | ||
|
||
// attach the camera to some block: | ||
someBlock3.addChild(camera); | ||
|
||
sceneBlock.addChild(someBlock3); | ||
|
||
// VERY IMPORTANT: actually set the camera. | ||
chesterGL.setCamera(camera); | ||
// === END CAMERA CODE === | ||
|
||
// add some action | ||
var bouncyFn = function () { | ||
if(typeof this.dz === "undefined") this.dz = 10; | ||
//this.setRotation(this.rotation + oneDeg); | ||
this.setPosition([this.position[0], this.position[1], this.position[2] + this.dz]); | ||
if (this.position[2] >= 200) { this.dz = -this.dz; } | ||
if (this.position[2] <= -200) { this.dz = -this.dz; } | ||
} | ||
|
||
someBlock.setUpdate(bouncyFn); | ||
someBlock2.setUpdate(bouncyFn); | ||
someBlock3.setUpdate(function () { | ||
this.setRotation(this.rotation - oneDeg/10); | ||
}); | ||
|
||
chesterGL.run(); | ||
// draw a single frame (for debug purposes) | ||
// chesterGL.drawScene(); | ||
}); | ||
} // setupGame() | ||
}); | ||
</script> | ||
<script type="text/javascript"> | ||
var _gaq = _gaq || []; | ||
_gaq.push(['_setAccount', 'UA-77863-9']); | ||
_gaq.push(['_trackPageview']); | ||
|
||
(function() { | ||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | ||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | ||
})(); | ||
</script> | ||
</head> | ||
<body> | ||
<div id="loading" style="position: absolute; z-index: 100;"></div> | ||
<div id="game-container"> | ||
<canvas id="demo-canvas" width="640" height="480"></canvas> | ||
<div> | ||
<span id="debug-info">00</span> ms per frame | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you that this is somewhat inefficient, also creating new elements on every frame is not so good for GC.
One way we could avoid this (calculation of the camera transform) is with lazy evaluation... not sure how to achieve this yet, but seems like a good idea