Chromium Code Reviews

Side by Side Diff: samples/o3d-webgl-samples/picking-more.html

Issue 2805101: o3d-webgl: Adding support for triangle fan/strip in picking. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « no previous file | samples/o3d-webgl/primitive.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright 2010, Google Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following disclaimer
13 in the documentation and/or other materials provided with the
14 distribution.
15 * Neither the name of Google Inc. nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 -->
31 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
32 "http://www.w3.org/TR/html4/loose.dtd">
33 <html>
34 <head>
35 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
36 <title>
37 Picking and IndexBuffers
38 </title>
39 <script type="text/javascript" src="../o3d-webgl/base.js"></script>
40 <script type="text/javascript" src="../o3djs/base.js"></script>
41 <script type="text/javascript" id="o3dscript">
42 o3djs.base.o3d = o3d;
43 o3djs.require('o3djs.webgl');
44 o3djs.require('o3djs.math');
45 o3djs.require('o3djs.rendergraph');
46 o3djs.require('o3djs.primitives');
47 o3djs.require('o3djs.material');
48 o3djs.require('o3djs.picking');
49
50 // global variables
51 var g_o3dElement;
52 var g_client;
53 var g_o3d;
54 var g_math;
55 var g_pack;
56 var g_viewInfo;
57 var g_eyePosition = [0, 0, 10];
58 var g_dataroot;
59 var g_pickManager;
60
61 /**
62 * Creates the client area.
63 */
64 function initClient() {
65 window.g_finished = false; // for selenium testing.
66 o3djs.webgl.makeClients(main);
67 }
68
69 /**
70 * Updates the span with the name of the shape that was picked, if anything.
71 * @param {event} e
72 */
73 function pick(e) {
74 var worldRay = o3djs.picking.clientPositionToWorldRay(
75 e.x,
76 e.y,
77 g_viewInfo.drawContext,
78 g_client.width,
79 g_client.height);
80 var pickInfo = g_pickManager.pick(worldRay);
81 var picked = 'nothing';
82 if (pickInfo) {
83 picked = pickInfo.shapeInfo.shape.name;
84 }
85 document.getElementById('picked').innerHTML = picked;
86 }
87
88 /**
89 * Rotates the scene if key is one of 'wasd'.
90 * @param {event} event
91 */
92 function rotateScene(event) {
93 // Ignore accelerator key messages.
94 if (event.metaKey)
95 return;
96
97 var keyChar = String.fromCharCode(o3djs.event.getEventKeyChar(event));
98 // Just in case they have capslock on.
99 keyChar = keyChar.toLowerCase();
100
101 var actionTaken = false;
102 var delta = 0.1;
103 switch(keyChar) {
104 case 'a':
105 g_dataroot.localMatrix =
106 g_math.matrix4.mul(g_dataroot.localMatrix,
107 g_math.matrix4.rotationY(-delta));
108 actionTaken = true;
109 break;
110 case 'd':
111 g_dataroot.localMatrix =
112 g_math.matrix4.mul(g_dataroot.localMatrix,
113 g_math.matrix4.rotationY(delta));
114 actionTaken = true;
115 break;
116 case 'w':
117 g_dataroot.localMatrix =
118 g_math.matrix4.mul(g_dataroot.localMatrix,
119 g_math.matrix4.rotationX(-delta));
120 actionTaken = true;
121 break;
122 case 's':
123 g_dataroot.localMatrix =
124 g_math.matrix4.mul(g_dataroot.localMatrix,
125 g_math.matrix4.rotationX(delta));
126 actionTaken = true;
127 break;
128 }
129 if (actionTaken) {
130 g_pickManager.update();
131 }
132 }
133
134 /**
135 * Initializes global variables, positions camera, draws shapes.
136 * @param {Array} clientElements Array of o3d object elements.
137 */
138 function main(clientElements) {
139 // Init global variables.
140 initGlobals(clientElements);
141
142 // Set up the view and projection transformations.
143 initContext();
144
145 // Add the shapes to the transform heirarchy.
146 createShapes();
147
148 o3djs.event.addEventListener(g_o3dElement, 'mousedown', pick);
149 o3djs.event.addEventListener(g_o3dElement, 'keypress', rotateScene);
150
151 // Create the pick manager.
152 g_pickManager = o3djs.picking.createPickManager(g_client.root);
153 g_pickManager.update();
154
155 window.g_finished = true; // for selenium testing.
156 }
157
158 /**
159 * Initializes global variables and libraries.
160 */
161 function initGlobals(clientElements) {
162 g_o3dElement = clientElements[0];
163 window.g_client = g_client = g_o3dElement.client;
164 g_o3d = g_o3dElement.o3d;
165 g_math = o3djs.math;
166
167 // Create a pack to manage the objects created.
168 g_pack = g_client.createPack();
169
170 // Creates a transform to put our data on.
171 g_dataroot = g_pack.createObject('Transform');
172 g_dataroot.parent = g_client.root;
173 g_dataroot.rotateY(-0.3);
174
175 // Create the render graph for a view.
176 g_viewInfo = o3djs.rendergraph.createBasicView(
177 g_pack,
178 g_client.root,
179 g_client.renderGraphRoot);
180 }
181 /**
182 * Sets up reasonable view and projection matrices.
183 */
184 function initContext() {
185 // Set up a perspective transformation for the projection.
186 g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
187 g_math.degToRad(30), // 30 degree frustum.
188 g_o3dElement.clientWidth / g_o3dElement.clientHeight, // Aspect ratio.
189 1, // Near plane.
190 5000); // Far plane.
191
192 // Set up our view transformation to look towards the world origin where the
193 // primitives are located.
194 g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
195 g_eyePosition, // eye
196 [0, 0, 0], // target
197 [0, 1, 0]); // up
198 }
199
200 /**
201 * Creates shapes using the primitives utility library, and adds them to the
202 * transform graph at the root node.
203 */
204 function createShapes() {
205 var triangleFan = createShape(g_o3d.Primitive.TRIANGLEFAN);
206 triangleFan.name = 'triangle-fan';
207 var triangleStrip = createShape(g_o3d.Primitive.TRIANGLESTRIP);
208 triangleStrip.name = 'triangle-strip';
209 var triangleList = createShape(g_o3d.Primitive.TRIANGLELIST);
210 triangleList.name = 'triangle-list';
211 var noIndexBuffer = createShape(-1);
212 noIndexBuffer.name = 'bufferless';
213
214 // Add the shapes to the transforms.
215 var transformTable = [
216 {shape: noIndexBuffer, translation: [-0.5, 1.25, 0]},
217 {shape: triangleFan, translation: [-1.0, -1.0, 0]},
218 {shape: triangleStrip, translation: [1.0, -1.0, 0]},
219 {shape: triangleList, translation: [0, 0, 0]}
220 ];
221
222 for (var tt = 0; tt < transformTable.length; ++tt) {
223 var transform = g_pack.createObject('Transform');
224 transform.addShape(transformTable[tt].shape);
225 transform.translate(transformTable[tt].translation);
226 transform.parent = g_dataroot;
227 }
228 }
229
230 /**
231 * Creates a shape that uses the requested indexing type.
232 * @param {o3d.Primitive.Type} indexType
233 */
234 function createShape(indexType) {
235 var material = g_pack.createObject('Material');
236 var effect = g_pack.createObject('Effect');
237 var shaderString = document.getElementById('shader').value;
238 effect.loadFromFXString(shaderString);
239 material.effect = effect;
240 material.drawList = g_viewInfo.performanceDrawList;
241 effect.createUniformParameters(material);
242
243 var shape = g_pack.createObject('Shape');
244 var primitive = g_pack.createObject('Primitive');
245 var streamBank = g_pack.createObject('StreamBank');
246
247 primitive.material = material;
248 primitive.owner = shape;
249 primitive.streamBank = streamBank;
250 primitive.primitiveType = indexType;
251 primitive.createDrawElement(g_pack, null);
252
253 var positionArray = [];
254
255 switch (indexType) {
256 case g_o3d.Primitive.TRIANGLEFAN:
257 positionArray = [
258 0.5, 0.0, 0.5, // 0
259 0.5, 0.0, -0.5, // 1
260 -0.5, 0.0, -0.5, // 2
261 -0.5, 0.0, 0.5, // 3
262 0.0, -1.0, 0.0 // 4
263 ];
264 indices = [4, 3, 2, 1, 0, 3]; // Square pyramid w/o the bottom.
265 primitive.numberPrimitives = 4;
266 primitive.numberVertices = 5;
267 break;
268 case g_o3d.Primitive.TRIANGLESTRIP:
269 positionArray = [
270 0.0, 0.0, 0.0, // 0
271 1.0, 0.0, 0.0, // 1
272 0.5, 0.0, -0.866, // 2
273 0.5, 0.866, -0.433 // 3
274 ];
275 indices = [0, 1, 3, 2, 0, 1]; // Triangular pyramid sort of shape.
276 primitive.numberPrimitives = 4;
277 primitive.numberVertices = 4;
278 break;
279 case g_o3d.Primitive.TRIANGLELIST:
280 positionArray = [
281 -0.5, -0.5, 0.5, // vertex 0
282 0.5, -0.5, 0.5, // vertex 1
283 -0.5, 0.5, 0.5, // vertex 2
284 0.5, 0.5, 0.5, // vertex 3
285 -0.5, 0.5, -0.5, // vertex 4
286 0.5, 0.5, -0.5, // vertex 5
287 -0.5, -0.5, -0.5, // vertex 6
288 0.5, -0.5, -0.5 // vertex 7
289 ];
290 indices = [
291 0, 1, 2, // face 1
292 2, 1, 3,
293 2, 3, 4, // face 2
294 4, 3, 5,
295 4, 5, 6, // face 3
296 6, 5, 7,
297 6, 7, 0, // face 4
298 0, 7, 1,
299 1, 7, 3, // face 5
300 3, 7, 5,
301 6, 0, 4, // face 6
302 4, 0, 2
303 ];
304 primitive.numberPrimitives = 12;
305 primitive.numberVertices = 8;
306 break;
307 default:
308 // No index buffer. Vertex data contains triples of triangles.
309 positionArray = [
310 -0.5, -0.5, 0.5,
311 0.5, -0.5, 0.5,
312 -0.5, 0.5, 0.5,
313 0.5, -0.5, 0.5,
314 1.5, -0.5, 0.5, // vertex 1
315 1.5, 0.5, 0.5 // vertex 3
316 ];
317 indices = null;
318 primitive.numberPrimitives = 2;
319 primitive.numberVertices = 6;
320 break;
321 }
322
323 // Create buffers containing the vertex data.
324 var positionsBuffer = g_pack.createObject('VertexBuffer');
325 var positionsField = positionsBuffer.createField('FloatField', 3);
326 positionsBuffer.set(positionArray);
327
328 if (indices) {
329 var indexBuffer = g_pack.createObject('IndexBuffer');
330 indexBuffer.set(indices);
331 primitive.indexBuffer = indexBuffer;
332 }
333
334 // Associate the positions Buffer with the StreamBank.
335 streamBank.setVertexStream(
336 g_o3d.Stream.POSITION, // semantic: This stream stores vertex positions
337 0, // semantic index: First (and only) position stream
338 positionsField, // field: the field this stream uses.
339 0); // start_index: How many elements to skip in the
340 // field.
341 return shape;
342 }
343 </script>
344 </head>
345 <body onload="initClient()">
346 <h1>More Picking</h1>
347 <p>This example demonstrates picking with custom shapes that use a variety of
348 index buffer formats. Back faces are culled (hidden) and cannot be picked.</p>
349 <p>
350 You picked: <span id="picked" style="color: red;">nothing</span>
351 </p>
352 <p>Rotate in the scene with WASD.</p>
353 <br/>
354 <!-- Start of O3D plugin -->
355 <div id="o3d" style="width: 600px; height: 600px;"></div>
356 <!-- End of O3D plugin -->
357
358 <textarea id="shader" style="display: none;">
359 attribute vec4 position;
360 uniform mat4 worldViewProjection;
361 varying vec4 pos;
362
363 /**
364 * The vertex shader simply transforms the input vertices to screen space.
365 */
366 void main() {
367 // Multiply the vertex positions by the worldViewProjection matrix to
368 // transform them to screen space.
369 gl_Position = worldViewProjection * position;
370 pos = position;
371 }
372
373 // #o3d SplitMarker
374 varying vec4 pos;
375
376 /**
377 * The fragment shader derives color based on the position.
378 */
379 void main() {
380 gl_FragColor = vec4(pos.xyz, 1.0);
381 }
382 </textarea>
383 </body>
384 </html>
OLDNEW
« no previous file with comments | « no previous file | samples/o3d-webgl/primitive.js » ('j') | no next file with comments »

Powered by Google App Engine