~roger-booth/rwboxy/main

« back to all changes in this revision

Viewing changes to view/canvas3dapi/Scene.js

  • Committer: Roger Booth
  • Date: 2009-04-02 05:18:46 UTC
  • Revision ID: roger.booth@gmail.com-20090402051846-drud06q7qbymimwj
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*Copyright (c) 2008 Seneca College
 
2
Modified by Roger Booth, 2008
 
3
Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/)
 
4
*/
 
5
 
 
6
// This script tries to follow Seneca College's idea of encapsulating
 
7
// most of the high-level functionality needed by Main.js
 
8
 
 
9
// Global variable for keeping track of this Class
 
10
var thisScn = null;
 
11
 
 
12
function Scene()
 
13
{
 
14
        // Engine Variables
 
15
        this.canvasVersion      = 0.0; // null, 1.1 or 2.0
 
16
        var glCanvas3D          = null; // OpenGL Context (Canvas)
 
17
        var camera              = null; // Reference to a Camera type
 
18
        var objList                     = new Array(); // An array of Objects to draw
 
19
        var exitFlag            = false; // Exits the main loop
 
20
        var cvs                 = null;
 
21
        var canvasHeight        = 0;
 
22
        var canvasWidth = 0;
 
23
        
 
24
        // Performance Variables
 
25
        var lastTimeTaken       = Date.now();
 
26
        var timerID             = 0;
 
27
        
 
28
        // External Color Structure
 
29
        var colorTiles            = null;
 
30
        
 
31
        // Cube-specific Data
 
32
        // Facing is related to winding...
 
33
        // idea was to indicate which sides are initially facing the camera.
 
34
        // if something isn't showing up as expected, change the facing
 
35
        // So far, only facing[0] has been needed.
 
36
        var facing = new Array();
 
37
        facing[0] = new Object();
 
38
        facing[0].blue='front';
 
39
        facing[0].red='front';
 
40
        facing[0].yellow='front';
 
41
        facing[0].white='back';
 
42
        facing[0].orange='back';
 
43
        facing[0].green='back';
 
44
        facing[1] = new Object();
 
45
        facing[1].blue='back';
 
46
        facing[1].red='back';
 
47
        facing[1].yellow='back';
 
48
        facing[1].white='front';
 
49
        facing[1].orange='front';
 
50
        facing[1].green='front';
 
51
 
 
52
        //What user, what cube name?
 
53
        var username    = null;
 
54
        var cubename    = null;
 
55
        //How is camera oriented? What's the angle for camera animation?
 
56
        var orientation    = null;
 
57
    var sceneRotAngle    = null;    
 
58
        
 
59
        // Operation queue for rendering
 
60
        var opQueue = new Array();
 
61
        
 
62
        // -------------------------------------------------------
 
63
        
 
64
        // Getters
 
65
        this.getCamera = function() { return camera; }
 
66
        this.getObjListSize = function() { return objList.length; }
 
67
        this.getGL = function() { return glCanvas3D; }
 
68
        this.getObj = function(indxNum)
 
69
        {
 
70
                if (isNaN(indxNum))
 
71
                {
 
72
                        logWarning('Scene::getObj() called with a parameter that\'s not a number');
 
73
                        return null;
 
74
                }
 
75
                // Check if the index that was asked for is inside the bounds of our array
 
76
                if (indxNum < 0 || indxNum >= objList.length)
 
77
                {
 
78
                        logWarning('Scene::getObj() called with ' + indxNum +', which is not betwen 0 and ' + objList.length);
 
79
                        return null;
 
80
                }
 
81
                
 
82
                // We do this because we dont want outsiders modifying the object list,
 
83
                // just the object themselves (ie. changing position, orientation, etc)
 
84
                return objList[indxNum];
 
85
        }
 
86
        this.getOrientation = function() { return orientation; }
 
87
        
 
88
        // Setters
 
89
        this.setUsername = function(user_name)
 
90
        {
 
91
                if (user_name != null) username = user_name;
 
92
                //logWarning('username: ' + username);
 
93
        }
 
94
        
 
95
        this.setCubename = function(cube_name)
 
96
        {
 
97
                if (cube_name != null) cubename = cube_name;
 
98
                //logWarning('cubename: ' + cubename);
 
99
        }
 
100
        this.setOrientation = function(cube_orient)
 
101
        {
 
102
        // Which way does the cube appear to be oriented?
 
103
                if (cube_orient != null) orientation = cube_orient;
 
104
//logWarning('orientation: ' + orientation);
 
105
        }
 
106
    this.setSceneRotAngle = function(scene_rot_angle)
 
107
        {
 
108
                sceneRotAngle = scene_rot_angle;
 
109
//logWarning('sceneRotAngle: ' + sceneRotAngle);        
 
110
        }
 
111
        // -------------------------------------------------------      
 
112
 
 
113
    this.queueLength = function()
 
114
        {
 
115
        return opQueue.length;
 
116
        }
 
117
 
 
118
    this.queueAction = function(action)
 
119
        {
 
120
        opQueue.push(action);
 
121
        }
 
122
        
 
123
    this.getAction = function()
 
124
        {
 
125
//logWarning('queue length: ' + opQueue.length);    
 
126
        return opQueue.shift();
 
127
        }
 
128
 
 
129
    this.unshiftAction = function(action)
 
130
        {
 
131
//logWarning('queued:' + action.type);
 
132
        opQueue.unshift(action);
 
133
        }
 
134
        // Acquire the OpenGL Context
 
135
        this.createScene = function(name)
 
136
        {
 
137
                if (glCanvas3D == null)
 
138
                {
 
139
                        // Get the Canvas Tag
 
140
                        cvs = document.getElementById(name);
 
141
                        // moz-gles11 is the only one that will work, for now
 
142
                        var prefferedContext1 = 'moz-gles11';
 
143
                        
 
144
                        // Try to get access to the OpenGL Canvas
 
145
                        try
 
146
                        {
 
147
                                this.canvasVersion = prefferedContext1;
 
148
                                glCanvas3D = cvs.getContext(prefferedContext1);
 
149
                        }catch (err)
 
150
                        {
 
151
                                try
 
152
                                {
 
153
                                        this.canvasVersion = prefferedContext2;
 
154
                                        glCanvas3D = cvs.getContext(prefferedContext2);
 
155
                                }catch(err)
 
156
                                {
 
157
                                        alert("Canvas3D Not Initialized.\n");
 
158
                                        this.canvasVersion = '';
 
159
                                        glCanvas3D = null;
 
160
                                }
 
161
                        }
 
162
                        
 
163
                        // Check the access to canvas
 
164
                        if (glCanvas3D != null)
 
165
                        {
 
166
                                //thisScn = this;
 
167
                //Points to global variable defined in Main.js
 
168
                thisScn = scn;
 
169
                                
 
170
                                // Get the size of the Canvas Space for Aspect Ratio calculation
 
171
                                canvasWidth = cvs.width;
 
172
                                canvasHeight = cvs.height;
 
173
                                
 
174
                                // Success
 
175
                                return true;
 
176
                        }
 
177
                        
 
178
                        // Failed, ATI Problem?
 
179
                        return false;
 
180
                }
 
181
                
 
182
                // Canvas already exists
 
183
                return false;
 
184
        }
 
185
        
 
186
        // Add a Camera to the Scene
 
187
        this.addCameraToScene = function(cam)
 
188
        {
 
189
                // Check to see if we were passed a correct Camera class
 
190
                if (cam instanceof ChaseCamera ||
 
191
                        cam instanceof FreeCamera ||
 
192
                        cam instanceof FixedCamera ||
 
193
                        cam instanceof PanCamera)
 
194
                {
 
195
                        camera = cam;
 
196
                        return true;
 
197
                }
 
198
                else
 
199
                        logWarning('Scene::addCameraToScene() called with a parameter that\'s not a ChaseCamera, FreeCamera, FixedCamera, or PanCamera');
 
200
                
 
201
                return false;
 
202
        }
 
203
        
 
204
        // Add objects to the scene
 
205
        this.addObjectToScene = function(obj)
 
206
        {
 
207
                // Check to see if we were passed a correct Object class
 
208
                if (obj instanceof Model ||
 
209
                        obj instanceof Primitive ||
 
210
                        obj instanceof FixedFacets ||
 
211
                        obj instanceof MobileFacets)
 
212
                {
 
213
                        objList.push(obj);
 
214
 
 
215
                        return true;
 
216
                }
 
217
                else
 
218
                        logWarning('Scene::addObjectToScene() called with a parameter that\'s not a Model, Primitive, or Cube');
 
219
                
 
220
                return false;
 
221
        }
 
222
 
 
223
        // Remove objects form the scene
 
224
        this.removeObjectFromScene = function(obj)
 
225
        {
 
226
                var i;
 
227
                
 
228
                // Check to see if we were passed a correct Camera class
 
229
                if (obj instanceof Model ||
 
230
                        obj instanceof Primitive)
 
231
                {
 
232
                        // Check against each item in the list
 
233
                        for (i = 0; i < objList.length; i++)
 
234
                        {
 
235
                                if (objList[i] == obj)
 
236
                                {
 
237
                                        // Remove the item
 
238
                                        objList.splice(i, 1);
 
239
 
 
240
                                        return true;
 
241
                                }
 
242
                        }
 
243
                }
 
244
                else
 
245
                        logWarning('Scene::removeObjectToScene() called with a parameter that\'s not a Model or Primitive');
 
246
                
 
247
                return false;
 
248
        }
 
249
 
 
250
 
 
251
        // Add color structure obtained from external source
 
252
        this.addColorsFromOutside = function(colortiles)
 
253
        {
 
254
                colorTiles = colortiles;
 
255
        }
 
256
 
 
257
 
 
258
        // Sets up OpenGL
 
259
        this.setupOpenGL = function()
 
260
        {
 
261
                if (glCanvas3D == null) return;
 
262
                
 
263
        if(this.canvasVersion == 'moz-gles11')
 
264
                {
 
265
                        // OpenGL Setup
 
266
                        glCanvas3D.matrixMode(glCanvas3D.PROJECTION);
 
267
                        glCanvas3D.loadIdentity();              
 
268
                        
 
269
                        // multiply the current projection matrix, which was just set to an identity matrix with a matrix 
 
270
                        // returned from the makePerspective function
 
271
                        // We need to use a custom perspective function instead of gluPerspective since the OpenGL ES 2.0 
 
272
                        // context does not support the gluPerspective function
 
273
                        glCanvas3D.multMatrix(makePerspective(45, canvasWidth / canvasHeight, 0.1, 200));
 
274
                        
 
275
                        glCanvas3D.matrixMode(glCanvas3D.MODELVIEW);
 
276
                        glCanvas3D.loadIdentity();
 
277
 
 
278
                }
 
279
                else
 
280
                        logWarning("setupOpenGL(): bad canvas version(" + scene.canvasVersion +  "), something's wrong with the library");
 
281
        }
 
282
        
 
283
        // This is the main loop that controls rendering
 
284
        this.startScene = function()
 
285
        {
 
286
                // Safety Checks
 
287
                if (glCanvas3D == null)
 
288
                {
 
289
                        logWarning('Scene::startScene() called but glCanvas3D is NULL');
 
290
                        return;
 
291
                }
 
292
                if (camera == null)
 
293
                {
 
294
                        logWarning('Scene::startScene() called but camera is NULL');
 
295
                        return;
 
296
                }
 
297
                
 
298
                // Set it all up
 
299
                this.setupOpenGL();
 
300
        this.render();
 
301
        // Create a timer for this object
 
302
                timerID = setInterval(this.render,25);
 
303
        }
 
304
        
 
305
        // Render Loop
 
306
        this.render = function()
 
307
        {
 
308
                // If a user wants to stop rendering, this is where it happens
 
309
                if (exitFlag)
 
310
                {
 
311
                        timerID = clearInterval(timerID);
 
312
                        return;
 
313
                }
 
314
                // Enable Lights -- Not!
 
315
        var followup;
 
316
        var action = thisScn.getAction();
 
317
                if (action)     {
 
318
//logWarning('Action type: ' + action.type);
 
319
            followup = action[action.type]();
 
320
            if (followup && followup == 'unshift'){
 
321
                thisScn.unshiftAction(action);
 
322
            }
 
323
            else if (followup && followup == 'push'){
 
324
                thisScn.queueAction(action);            
 
325
            }
 
326
        }
 
327
        if ((thisScn.queueLength() == 0) && username && cubename){
 
328
//logWarning('queueing a checkRemote job');
 
329
            var act = new Action('checkRemote',null,null,orientation,0,username,cubename); 
 
330
            thisScn.queueAction(act);
 
331
        }
 
332
        if (followup && (followup != 'push')){
 
333
                        // Clear the screen
 
334
                        glCanvas3D.clearColor(0.4, 0.4, 0.6, 1.0);
 
335
                        glCanvas3D.clear(glCanvas3D.COLOR_BUFFER_BIT | glCanvas3D.GL_DEPTH_BUFFER_BIT);
 
336
                        
 
337
                        // Set the camera in world space
 
338
                        camera.applyToWorld(glCanvas3D, thisScn);
 
339
                        
 
340
                        // Do Rendering
 
341
                        // bracket object rendering in Push, Pop
 
342
                        glCanvas3D.pushMatrix();
 
343
            thisScn.rotateScene(sceneRotAngle);
 
344
            thisScn.renderObjects(action.face);
 
345
                        glCanvas3D.popMatrix();
 
346
                        
 
347
                        // Swap buffers to render
 
348
                        glCanvas3D.swapBuffers();
 
349
                }
 
350
        }
 
351
        
 
352
    // Rotate scene (coordinate system) around y-axis
 
353
        this.rotateScene = function(ccwAngle)
 
354
        {
 
355
//logWarning('ccwAngle: ' + ccwAngle);    
 
356
        if (ccwAngle && (ccwAngle <= 180)){
 
357
            glCanvas3D.rotate(ccwAngle, 0, 1, 0);
 
358
        }
 
359
        }
 
360
    
 
361
        // Renders all objects to the screen
 
362
        this.renderObjects = function(face)
 
363
        {
 
364
//logWarning('face: ' + face);    
 
365
        // 'this' is only passed to check the context... we don't really need it
 
366
                // because we only support context 1.1 for now
 
367
                // Two objects: one fixed, one rotating
 
368
                objList[0].render(glCanvas3D, this, face, facing[0], colorTiles);
 
369
                objList[1].render(glCanvas3D, this, face, facing[0], colorTiles);
 
370
        }
 
371
        
 
372
        // Flags the main loop for exit
 
373
        this.stopScene = function()
 
374
        {
 
375
                // This flags the main loop to exit gracefully
 
376
                exitFlag = true;
 
377
        }
 
378
}