|
MathWorx | |||||||
PREV NEXT | FRAMES NO FRAMES |
This file defines a 3D scene and the requisite methods.
Class Summary | |
Scene3D | Scene3D defines a new 3D scene (shocking, I know). |
/**MathWorx Copyright (c) 2008 Shane Steinert-Threlkeld Dual-licensed under the MIT and GNU GPL Licenses. For more information, see LICENSE file */ //Things to think about: depth sorting, sprite buttons to rotate camera, change focus, etc. /**@fileoverview This file defines a 3D scene and the requisite methods. */ dependencies = ['point3D', 'Plane']; require(dependencies); /**The constructor function for a new Scene3D object. @class Scene3D defines a new 3D scene (shocking, I know). A 3D Scene has two main components: objects (to be displayed), and a camera (from which to view the objects). In this model of a 3D scene, the camera is the main mover, not the objects (though they can be moved). A view plane is defined through the origin with a normal in the direction from the origin to the camera; the objects are projected onto this view plane, which is then matched up with the 2D plane of the screen.<br /> Most methods return this, so calls can be made sequentially. @requires point3D @requires Plane @param {Array} objs an Array of Object3D objects to be displayed @param {point3D} camera the position of the camera (as a point3D object); used to generate initial focus and view plane; also used to define this.camera = {loc: point3D, theta: angle, phi: angle} @constructor */ function Scene3D(objs, camera) { /**The "camera" is the point from which the objects are being viewed. It is a dynamically defined Object with three properties: loc (point3D), theta (Number), and phi (Number). Theta is the angle between the positive x axis and the orthogonal projection of the camera onto the XY-plane. Phi is the angle between the camera and the positive z-axis. @type point3D */ this.camera = {loc: point3D.zero, theta: 0, phi: 0}; /**The focus is the distance between the camera and the origin (in world coordinates) @type Number */ this.focus = 0; /**The objects to be viewed/displayed. An array of Object3D objects. @type Array */ this.objects = new Array(); /**The view plane, onto which the objects are projected. @type Plane */ this.plane = Plane.XY; if(camera) { if(camera instanceof point3D) { var iphi = Math.atan2(Math.sqrt(camera.x*camera.x + camera.y*camera.y), camera.z); var itheta = Math.atan2(camera.y, camera.x); this.camera = {loc: camera, theta: itheta, phi: iphi}; } } else { this.camera = {loc: new point3D(0, 0, 100), theta: 0, phi: 0}; } this.objects = objs; this.focus = this.camera.loc.getLength(); //NOTE: this.camera.loc will be normalized by Plane constructor function this.plane = new Plane(point3D.zero, this.camera.loc); } Scene3D.prototype = { /**Draws the 3D scene, with the specified objects. REQUIRES jQuery SVG. @param {Array} objs an array of object indices to be displayed. @param {Object} svg the jQuery SVG object in which to draw the scene @param {Object} settings the settings to give to each line of the objects; can be an Array of settings, where each index of the array corresponds to the index of the objects passed to this function */ draw: function(objs, svg, settings) { //this.depthSort(); var objects = objs; if(!(settings instanceof Array)) { var set = settings; } for(var i = 0; i < objects.length; i++) { //after this, each object3D also has vertices2D array objects[i].viewIn(this.camera).to2D(this.focus).draw(svg, (set || settings[i])); } }, /**Empties the SVG canvas supplied. @param {Object} svg the jQuery SVG root canvas @return {Scene3D} this Scene3D object, so calls can be stringed together */ emptySVG: function(svg) { svg.clear(); return this; }, /**Sets the focus (distance between Origin and camera). @param {Number} dist the new focal distance @return {Scene3D} this Scene3D object, with updated focus distance and matching camera position */ setFocus: function(dist) { this.focus = dist; this.camera.loc = this.camera.loc.multiplyBy(this.focus/this.camera.loc.getLength()); return this; }, /**Moves the camera to a new position. Parameters are two angles, one in the XY-plane from the positive x-axis and the other from the positive z-axis. @param {Number} theta the degree (in radians) to rotate the camera from the positive x-axis @param {Number} phi the degree (in radians) to rotate the camera from the positive z-axis @return {Scene3D} this Scene3D object, with updated camera and view plane */ rotateCamera: function(theta, phi) { var itheta = theta; var iphi = phi; var x = Math.sin(iphi)*Math.cos(itheta); var y = Math.sin(iphi)*Math.sin(itheta); var z = Math.cos(iphi); var norm = new point3D(x, y, z); this.plane = new Plane(point3D.zero, norm); this.camera = {loc: norm.multiplyBy(this.focus), theta: itheta, phi: iphi}; //creates a new point3D return this; }, /** FINISH THIS METHOD ONCE ALL THE REQUIRED METHODS / OBJECT3D ARE DEFINED depthSort: function() { var dist, mids; var faceDists = new Array(); for(i = 0; i < this.objects.length; i++) { mids = this.objects[i].getMidpoints(); for(j = 0; j < mids.length; j++) { dist = (this.camera.subtract(mids[i])).getLength(); } } }, */ /**Add an object to the 3D Scene. @param {Object3D} obj the object to be added to the 3D Scene @return {Scene3D} this Scene3D, with the object added (returns null if obj is not an Object3D) */ addObject: function(obj) { if(!(obj instanceof Object3D)) { return null; } this.objects.push(obj); return this; }, /**Returns a string representation of the Scene (camera and objects). @return {String} the location of the camera plus a list of all the objects @see Object3D#toString */ toString: function() { return "camera: " + this.camera.loc + "\n----------\nobjects:\n-----\n" +this.objects.join("\n----------\n"); } } //end Scene3D prototype
|
MathWorx | |||||||
PREV NEXT | FRAMES NO FRAMES |