mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Proof of concept sphere thing for metavoxels.
This commit is contained in:
parent
a5c8531aa1
commit
e6a41b2003
2 changed files with 176 additions and 11 deletions
171
interface/resources/scripts/sphere.js
Normal file
171
interface/resources/scripts/sphere.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
//
|
||||
// sphere.js
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 12/17/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
function strictIndexOf(array, element) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (array[i] == element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
var colorIndex;
|
||||
var normalIndex;
|
||||
var visitor;
|
||||
var info;
|
||||
|
||||
var MAX_DEPTH = 5;
|
||||
|
||||
var sphereCenter = [ 0.5, 0.5, 0.5 ];
|
||||
var sphereColor = 0xFFFF00FF;
|
||||
var sphereRadius = 0.25;
|
||||
var sphereRadiusSquared = sphereRadius * sphereRadius;
|
||||
|
||||
function lengthSquared(x, y, z) {
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
function setNormal(vector) {
|
||||
if (normalIndex != -1) {
|
||||
var length = Math.sqrt(lengthSquared(vector[0], vector[1], vector[2]));
|
||||
if (length == 0.0) {
|
||||
info.attributeValues[normalIndex] = 0x007F00;
|
||||
|
||||
} else {
|
||||
var scale = 127.0 / length;
|
||||
info.attributeValues[normalIndex] =
|
||||
(Math.floor(vector[0] * scale) & 0xFF) << 16 |
|
||||
(Math.floor(vector[1] * scale) & 0xFF) << 8 |
|
||||
Math.floor(vector[2] * scale) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function guide(minimum, size, depth) {
|
||||
info.minimum = minimum;
|
||||
info.size = size;
|
||||
|
||||
// start with a relative fast bounding volume test to find most non-intersecting states
|
||||
var maximum = [ minimum[0] + size, minimum[1] + size, minimum[2] + size ];
|
||||
if (minimum[0] >= sphereCenter[0] + sphereRadius ||
|
||||
minimum[1] >= sphereCenter[1] + sphereRadius ||
|
||||
minimum[2] >= sphereCenter[2] + sphereRadius ||
|
||||
maximum[0] <= sphereCenter[0] - sphereRadius ||
|
||||
maximum[1] <= sphereCenter[1] - sphereRadius ||
|
||||
maximum[2] <= sphereCenter[2] - sphereRadius) {
|
||||
info.isLeaf = true;
|
||||
if (colorIndex != -1) {
|
||||
info.attributeValues[colorIndex] = 0x0;
|
||||
}
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
var halfSize = size / 2;
|
||||
var center = [ minimum[0] + halfSize, minimum[1] + halfSize, minimum[2] + halfSize ];
|
||||
var vector = [ center[0] - sphereCenter[0], center[1] - sphereCenter[1], center[2] - sphereCenter[2] ];
|
||||
|
||||
// count the number of points inside the sphere
|
||||
var inside = 0;
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
|
||||
// see if all points are in the sphere
|
||||
if (inside == 8) {
|
||||
info.isLeaf = true;
|
||||
if (colorIndex != -1) {
|
||||
info.attributeValues[colorIndex] = sphereColor;
|
||||
}
|
||||
setNormal(vector);
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
// if we've reached max depth, compute alpha using a volume estimate
|
||||
if (depth == MAX_DEPTH) {
|
||||
info.isLeaf = true;
|
||||
if (inside >= 3) {
|
||||
if (colorIndex != -1) {
|
||||
info.attributeValues[colorIndex] = sphereColor;
|
||||
}
|
||||
setNormal(vector);
|
||||
|
||||
} else {
|
||||
if (colorIndex != -1) {
|
||||
info.attributeValues[colorIndex] = 0x0;
|
||||
}
|
||||
}
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
// recurse
|
||||
info.isLeaf = false;
|
||||
if (!visitor.visit(info)) {
|
||||
return;
|
||||
}
|
||||
depth += 1;
|
||||
guide(minimum, halfSize, depth);
|
||||
guide([ center[0], minimum[1], minimum[2] ], halfSize, depth);
|
||||
guide([ minimum[0], center[1], minimum[2] ], halfSize, depth);
|
||||
guide([ center[0], center[1], minimum[2] ], halfSize, depth);
|
||||
guide([ minimum[0], minimum[1], center[2] ], halfSize, depth);
|
||||
guide([ center[0], minimum[1], center[2] ], halfSize, depth);
|
||||
guide([ minimum[0], center[1], center[2] ], halfSize, depth);
|
||||
guide([ center[0], center[1], center[2] ], halfSize, depth);
|
||||
}
|
||||
|
||||
(function(visitation) {
|
||||
var attributes = visitation.visitor.getAttributes();
|
||||
colorIndex = strictIndexOf(attributes, AttributeRegistry.colorAttribute);
|
||||
normalIndex = strictIndexOf(attributes, AttributeRegistry.normalAttribute);
|
||||
visitor = visitation.visitor;
|
||||
info = { attributeValues: new Array(attributes.length) };
|
||||
|
||||
// have the sphere orbit the center and pulse in size
|
||||
var time = new Date().getTime();
|
||||
var ROTATE_PERIOD = 400.0;
|
||||
sphereCenter[0] = 0.5 + 0.25 * Math.cos(time / ROTATE_PERIOD);
|
||||
sphereCenter[2] = 0.5 + 0.25 * Math.sin(time / ROTATE_PERIOD);
|
||||
var PULSE_PERIOD = 300.0;
|
||||
sphereRadius = 0.25 + 0.0625 * Math.cos(time / PULSE_PERIOD);
|
||||
sphereRadiusSquared = sphereRadius * sphereRadius;
|
||||
|
||||
guide(visitation.info.minimum, visitation.info.size, 0);
|
||||
})
|
|
@ -6,6 +6,8 @@
|
|||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
@ -41,17 +43,9 @@ void MetavoxelSystem::init() {
|
|||
|
||||
_data.setAttributeValue(p1, AttributeValue(color, encodeInline(qRgba(0xFF, 0xFF, 0xFF, 0xFF))));
|
||||
|
||||
QScriptValue guideFunction = _scriptEngine.evaluate(
|
||||
"(function(visitation) { "
|
||||
" var attributes = visitation.visitor.getAttributes();"
|
||||
" var colorIndex = attributes.indexOf(AttributeRegistry.colorAttribute);"
|
||||
" var normalIndex = attributes.indexOf(AttributeRegistry.normalAttribute);"
|
||||
" for (var i = 0; i < attributes.length; i++) {"
|
||||
" print(attributes[i].getName() + ' ');"
|
||||
" }"
|
||||
" print('\\n');"
|
||||
" visitation.visitor.visit(visitation.info);"
|
||||
"})");
|
||||
QFile scriptFile("resources/scripts/sphere.js");
|
||||
scriptFile.open(QIODevice::ReadOnly);
|
||||
QScriptValue guideFunction = _scriptEngine.evaluate(QTextStream(&scriptFile).readAll());
|
||||
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
|
||||
encodeInline(PolymorphicDataPointer(new ScriptedMetavoxelGuide(guideFunction)))));
|
||||
|
||||
|
|
Loading…
Reference in a new issue