|
185 | 185 |
|
186 | 186 | document.getElementById("occlusion-toggle").addEventListener("change", function() { |
187 | 187 | occlusionCullingEnabled = this.checked; |
188 | | - for(var i = 0, len = isDrawNodes.length; i < len; i++) { |
189 | | - isDrawNodes[i] = true; |
| 188 | + for(var i = 0, len = nodes.length; i < len; i++) { |
| 189 | + nodes[i].isDrawNode = true; |
190 | 190 | } |
191 | 191 | }); |
192 | 192 |
|
|
397 | 397 | vaobbox: sphereBBoxArray, |
398 | 398 | bboxNumVertices: sphere.bbox.bbox.positions.length / 3, |
399 | 399 |
|
400 | | - query: gl.createQuery() |
| 400 | + query: gl.createQuery(), |
| 401 | + isDrawNode: true |
401 | 402 | }; |
402 | 403 |
|
403 | 404 | utils.xformMatrix(nodes[i].modelMatrix, nodes[i].translate, null, nodes[i].scale); |
|
424 | 425 | var tmpVec4a = vec4.create(); |
425 | 426 | var tmpVec4b = vec4.create(); |
426 | 427 | var tmpMat4 = mat4.create(); |
427 | | - nodes.sort(function(a, b){ |
| 428 | + function sortNodes(a, b) { |
428 | 429 | // sort nodes by dist to eye (via pos in view space) |
429 | 430 | // we assume their relative order is static in this demo |
430 | | - vec4.set(tmpVec4a, a.translate.x, a.translate.y, a.translate.z, 1.0); |
431 | | - vec4.set(tmpVec4b, b.translate.x, b.translate.y, b.translate.z, 1.0); |
| 431 | + vec4.set(tmpVec4a, a.translate[0], a.translate[1], a.translate[2], 1.0); |
| 432 | + vec4.set(tmpVec4b, b.translate[0], b.translate[1], b.translate[2], 1.0); |
432 | 433 |
|
433 | 434 | mat4.mul(tmpMat4, viewMatrix, a.modelMatrix); |
434 | 435 | vec4.transformMat4(tmpVec4a, tmpVec4a, tmpMat4); |
435 | 436 | mat4.mul(tmpMat4, viewMatrix, b.modelMatrix); |
436 | 437 | vec4.transformMat4(tmpVec4b, tmpVec4b, tmpMat4); |
437 | 438 |
|
438 | 439 | vec4.sub(tmpVec4a, tmpVec4a, tmpVec4b); |
439 | | - if (tmpVec4a[2] !== 0) { |
440 | | - return tmpVec4a[2]; |
441 | | - } |
442 | | - if (tmpVec4a[0] !== 0) { |
443 | | - return tmpVec4a[0]; |
444 | | - } |
445 | | - return -tmpVec4a[1]; |
446 | | - }); |
| 440 | + return -tmpVec4a[2]; |
| 441 | + } |
447 | 442 |
|
448 | 443 | // top down assist camera |
449 | 444 | var projMatrixAssistCam = mat4.create(); |
|
486 | 481 |
|
487 | 482 | var image = new Image(); |
488 | 483 | var firstFrame = true; |
489 | | - var isDrawNodes = new Array(nodes.length); |
490 | | - for (var i = 0, len = isDrawNodes.length; i < len; ++i) { |
491 | | - isDrawNodes[i] = true; |
492 | | - } |
493 | 484 | var invisibleNodesCount = 0; |
494 | 485 |
|
495 | 486 | image.onload = function() { |
|
520 | 511 | var doquery = true; |
521 | 512 | var samplesPassed; |
522 | 513 |
|
| 514 | + var i, len = nodes.length; |
523 | 515 |
|
524 | 516 | var t = 0; |
525 | 517 | function draw() { |
526 | 518 | t += 0.01; |
527 | 519 | invisibleNodesCount = 0; |
528 | 520 |
|
| 521 | + // transform nodes |
| 522 | + for (i = 0; i < len; ++i) { |
| 523 | + node = nodes[i]; |
| 524 | + |
| 525 | + node.rotate[1] = Math.PI / 6 * (Math.sin(t - Math.PI / 2) + 1); |
| 526 | + |
| 527 | + utils.xformMatrix(node.modelMatrix, node.translate, null, node.scale); |
| 528 | + mat4.fromYRotation(rotationMatrix, node.rotate[1]); |
| 529 | + mat4.multiply(node.modelMatrix, rotationMatrix, node.modelMatrix); |
| 530 | + } |
| 531 | + |
| 532 | + if (occlusionCullingEnabled) { |
| 533 | + // sort by view distance |
| 534 | + nodes.sort(sortNodes); |
| 535 | + } |
| 536 | + |
529 | 537 | gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); |
530 | 538 | gl.clearColor(0, 0, 0, 1); |
531 | 539 | gl.enable(gl.DEPTH_TEST); |
532 | 540 | gl.colorMask(true, true, true, true); |
533 | 541 | gl.depthMask(true); |
534 | 542 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
535 | 543 |
|
536 | | - for (var i = 0, len = nodes.length; i < len; ++i) { |
| 544 | + for (i = 0; i < len; ++i) { |
537 | 545 | node = nodes[i]; |
538 | 546 | bbox = node.bbox; |
539 | | - |
540 | | - node.rotate[1] = Math.PI / 6 * (Math.sin(t - Math.PI / 2) + 1); |
541 | | - |
542 | | - utils.xformMatrix(node.modelMatrix, node.translate, null, node.scale); |
543 | | - mat4.fromYRotation(rotationMatrix, node.rotate[1]); |
544 | | - mat4.multiply(node.modelMatrix, rotationMatrix, node.modelMatrix); |
545 | 547 |
|
546 | 548 | if (occlusionCullingEnabled) { |
547 | 549 | // use occlusion query with drawing bounding box |
|
565 | 567 | if (samplesPassed == 0) { |
566 | 568 | // console.log('invisible node ' + i); |
567 | 569 | isVisible = false; |
568 | | - isDrawNodes[i] = false; |
| 570 | + node.isDrawNode = false; |
569 | 571 | } |
570 | 572 | else { |
571 | 573 | isVisible = true; |
572 | | - isDrawNodes[i] = true; |
| 574 | + node.isDrawNode = true; |
573 | 575 | } |
574 | 576 | } |
575 | 577 | else { |
576 | 578 | // query is not ready, use visible info from previous frame (to make assist cam looks correct) |
577 | 579 | // if we want to be conservative, simple set isVisible to true |
578 | | - isVisible = isDrawNodes[i]; |
| 580 | + isVisible = node.isDrawNode; |
579 | 581 | doquery = false; |
580 | 582 | } |
581 | 583 | } |
|
629 | 631 | gl.clearColor(0.3, 0.3, 0.3, 1); |
630 | 632 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
631 | 633 | gl.useProgram(programAssistCam); |
632 | | - for (i = 0, len = nodes.length; i < len; ++i) { |
633 | | - if (isDrawNodes[i]) { |
634 | | - node = nodes[i]; |
| 634 | + for (i = 0; i < len; ++i) { |
| 635 | + node = nodes[i]; |
| 636 | + if (node.isDrawNode) { |
635 | 637 | gl.bindVertexArray(node.vao); |
636 | 638 | gl.uniformMatrix4fv(modelMatrixLocationAssistCam, false, node.modelMatrix); |
637 | 639 | gl.drawElements(gl.TRIANGLES, node.indicesLength, gl.UNSIGNED_SHORT, 0); |
|
0 commit comments