aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes/RDGE/src/core/script/init_state.js
blob: 1fbc81f3f511fe38021cad623e7637a63a8ee0c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
</copyright> */

var RDGE = RDGE || {};

// init the view
RDGE.LoadState = function(userRunState, context) {
    this.name					= "LoadState";
    this.userRunState           = userRunState !== undefined ? userRunState : new RDGE.core.RDGEState;
	this.hasUserState			= userRunState !== undefined ? true : false;
	this.renderer				= context.renderer;
	this.loadingDone			= false;
	this.stateManager			= context.ctxStateManager;
	this.sceneLoadQueue			= [];
	this.textureLoadQueue		= [];
};

RDGE.LoadState.prototype.loadScene = function (addr, sceneName) {
    var request = new RDGE.sceneRequestDef(addr, sceneName);
	request.doSceneRequest = true;
	this.sceneLoadQueue.push( request );
};

RDGE.LoadState.prototype.loadTexture = function (textureObject) {
    if (this.stateManager.currentState().name != "LoadState") {
		this.stateManager.PushState( this.stateManager.RDGEInitState, "noInit" );
	}
	
	this.textureLoadQueue.push(textureObject);
};

RDGE.LoadState.prototype.Init = function () {
    if (this.sceneName) {
		this.loadScene("assets_web/mesh/" + this.sceneName + ".json", this.sceneName);
	}

	if (this.hasUserState && this.userRunState && this.userRunState.onLoadState)
		this.userRunState.onLoadState();
};

RDGE.LoadState.prototype.ReInit = function () {
	if (this.hasUserState && this.userRunState && this.userRunState.onLoadState)
		this.userRunState.onLoadState();
};

RDGE.LoadState.prototype.Resize = function () {
    if (RDGE.globals.engine.lastWindowWidth == window.innerWidth && RDGE.globals.engine.lastWindowHeight == window.innerHeight) {
		this.userRunState.resize();
        RDGE.globals.engine.lastWindowWidth = window.innerWidth;
        RDGE.globals.engine.lastWindowHeight = window.innerHeight;
}
};

RDGE.LoadState.prototype.Update = function (dt) {
	// for the current scene go through processing steps
	var sceneLoadTop = this.sceneLoadQueue.length - 1;
	var texLoadTop	= this.textureLoadQueue.length - 1;
	
    if (sceneLoadTop > -1) {
		var curSceneReq = this.sceneLoadQueue[sceneLoadTop];
		
		// check for completed mesh requests and load the data
        RDGE.globals.meshMan.processMeshData();

        if (curSceneReq.doSceneRequest) {
			curSceneReq.requestScene();
		}
        else if (curSceneReq.requestComplete) {
            if (curSceneReq.sceneBeginProcessing) {
				// Load meshes attached to the scene
                curSceneReq.scene = new RDGE.SceneGraph(curSceneReq.rawData);
				curSceneReq.scene.enableShadows( true );
                RDGE.globals.engine.AddScene(curSceneReq.name, curSceneReq.scene);

				// setup the scene and save a map of mesh names
				// that will be check off as the meshes load
				curSceneReq.scene.Traverse(curSceneReq.sceneProcessor, false);
				
				// processing is complete
				curSceneReq.sceneBeginProcessing = false;
			}
			// if we are here than the scene is processed but meshes are still loading/processing asynchronously
            else if (curSceneReq.processingComplete()) {
				// pop the head node
				var sceneReq = this.sceneLoadQueue.shift();
				this.userRunState.onComplete(sceneReq.name, sceneReq.scene);	
			}
		}
		
	}
	
	// load any waiting textures
    while (this.textureLoadQueue.length > 0) {
		this.renderer.commitTexture( this.textureLoadQueue.shift() );
	}
	
	// if there is nothing left to load move back to the run state
    if (this.sceneLoadQueue.length == 0 && this.textureLoadQueue.length == 0) {
		// loaded... remove the state
        var stateMan = RDGE.globals.engine.getContext().ctxStateManager;
		stateMan.PopState();
	}
	
    if (RDGE.globals.engine.getContext().getScene() && RDGE.globals.engine.getContext().getScene() != "not-ready" && this.stateManager.RDGERunState.initialized)
		this.userRunState.update(dt);	
};

RDGE.LoadState.prototype.Draw = function () {
	this.renderer._clear();
	
    if (RDGE.globals.engine.getContext().getScene() && RDGE.globals.engine.getContext().getScene() != "not-ready" && this.stateManager.RDGERunState.initialized)
		this.userRunState.draw();	
};
	
RDGE.LoadState.prototype.Shutdown = function () {
};

RDGE.LoadState.prototype.LeaveState = function () {
    if (this.userRunState.onComplete != undefined) {
		this.userRunState.onComplete();	
	}
};

RDGE.LoadState.prototype.MakeSceneRequest = function (addr, name) {

	this.hasScene = true;
	this.lastSceneName = name;
    var request = new XMLHttpRequest();
    request.initState = this;
    RDGE.globals.engine.getContext().sceneGraphMap[name] = "not-ready";
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            if (request.status == 200 || window.location.href.indexOf("http") == -1) {
                this.initState.scene = eval("(" + request.responseText + ")"); //retrieve result as an JavaScript object
                this.initState.loadingDone = true;
            }
            else {
                alert("An error has occured making the request");
            }
        }
    };

    request.open("GET", addr, true);
    request.send(null);
};

// scene traversal functor to setup the scene
RDGE.SetupScene = function ()
{
	this.renderer			= RDGE.globals.engine.getContext().renderer;
	this.meshLoadingMap		= [];
	this.onMeshLoaded = function (meshName) {
		// if the mesh was loading (and is defined) mark it as no longer loading
		if(this.meshLoadingMap[meshName])
			this.meshLoadingMap[meshName].stillLoading = false;
	};
	
	// set a call back handler to notify us when a mesh is loaded
	RDGE.globals.meshMan.addOnLoadedCallback( this );
};

RDGE.SetupScene.prototype.process = function (trNode, parent) {
    RDGE.verifyTransformNode(trNode);

	// create and assign parent node
	trNode.parent = parent;

    if (trNode.local !== undefined) {
        trNode.local = RDGE.mat4.transpose(trNode.local);
	}
  
    if (((trNode.materialNode || {}).meshNode || {}) != 'undefined') {
        if (trNode.materialNode !== undefined) {

            var lookup = RDGE.globals.meshMan.loadMesh(trNode.materialNode.meshNode.mesh);
			
			//~~~~ Hack - the mesh node should be placed in an array of meshes under the transform when exported
			trNode.meshes.push(trNode.materialNode.meshNode);

			// if the mesh is not loaded add it to our map
            if (lookup == null) {
				// mark this mesh as loading
				this.meshLoadingMap[trNode.materialNode.meshNode.mesh.name] = { 'stillLoading':true, 'remotelyLoading':false };
			}
            else {
				// just because its in the mesh manager doesn't mean its ready, but
				// if the primitive exists than it is ready to go
                if (lookup.primitive) {
					// create the buffer for this renderer
					this.renderer.createPrimitive(lookup.primitive);
				}
				// first see if this scene is the scene already loading this mesh
                else if (!this.meshLoadingMap[trNode.materialNode.meshNode.mesh.name]) {
					// mark this mesh as loading
					this.meshLoadingMap[trNode.materialNode.meshNode.mesh.name] = { 'stillLoading':true, 'remotelyLoading':true };
				}
					
			}
			
			//add set texture helper function
            RDGE.verifyMaterialNode(trNode.materialNode);

			var mapLookUp = [];
			mapLookUp["TEX_DIF"]  = {'slot':0, 'uni':"colMap"};   // type to texture slot look up
			mapLookUp["TEX_SPEC"] = {'slot':1, 'uni':"envMap"};
			mapLookUp["TEX_NORM"] = {'slot':2, 'uni':"normalMap"};
			mapLookUp["TEX_GLOW"] = {'slot':3, 'uni':"glowMap"};
      
			// get handle and setup slot bindings
			var texList = trNode.materialNode.textureList;
			var extractedList = [];
            for (var i = 0; i < texList.length; ++i) {
				var handle = this.renderer.getTextureByName(texList[i].name);
                extractedList[i] = { 'name': mapLookUp[texList[i].type].uni, 'handle': handle, 'unit': mapLookUp[texList[i].type].slot, 'type': RDGE.UNIFORMTYPE.TEXTURE2D };
			}
			
			trNode.materialNode.textureList = extractedList;
		}
	}
  
    if ((trNode.lightNode || {}) != 'undefined') {
        if (trNode.lightNode !== undefined) {
			trNode.lightNode.parent = trNode;
            RDGE.globals.engine.lightManager.setMapping(trNode.lightNode, trNode.lightNode.links);
	}
}
};


RDGE.sceneRequestDef = function (addr, sceneName) {
	this.name					= sceneName;
	this.addr					= addr;
	this.sceneBeginProcessing	= false;
	this.requestComplete		= false;
    this.sceneProcessor = new RDGE.SetupScene();
	this.doSceneRequest			= false;
	
	/*
	 *	@return - returns true when all meshes for the request are done
	 */
    this.processingComplete = function () {
        for (var m in this.sceneProcessor.meshLoadingMap) {
			// if a mesh is still loading than loading is not complete
            if (this.sceneProcessor.meshLoadingMap[m].stillLoading == false) {
				
                if (this.sceneProcessor.meshLoadingMap[m].remotelyLoading == true) {
					// In this case we need to generate the buffers on our render device
                    var mesh = RDGE.globals.meshMan.getModelByName(m);
					this.sceneProcessor.renderer.createPrimitive(mesh.primitive);
				}
			}
            else {
				return false;				
			}
		}
		
		// loading done
		return true;
    };
	
    this.requestScene = function () {
		this.doSceneRequest = false;
		
		var request = new XMLHttpRequest();
		request.handler = this;
		
		// set this scene as not-ready just in case anyone is looking for it
        RDGE.globals.engine.getContext().sceneGraphMap[name] = "not-ready";
		
		// on request complete - set the flags of this request to trigger the next step in loading
        request.onreadystatechange = function () {
			if (request.readyState == 4) {
                if (request.status == 200 || window.location.href.indexOf("http") == -1) {
					this.handler.rawData = eval("(" + request.responseText + ")"); //retrieve result as an JavaScript object
					this.handler.requestComplete = true;
					this.handler.sceneBeginProcessing = true;
				}
                else {
					alert("An error has occured making the request");
				}
			}
		}
		
		request.open("GET", addr, true);
		request.send(null);
    };
};