Skip to content

Commit

Permalink
Working on bounding box calculation for issue #22 and briefly started…
Browse files Browse the repository at this point in the history
… thinking on generating the appropriate vertex shader.
  • Loading branch information
rehno-lindeque committed Nov 29, 2011
1 parent 305c311 commit ad12d56
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 60 deletions.
89 changes: 64 additions & 25 deletions src/compile.asm.bounds.coffee
Original file line number Diff line number Diff line change
@@ -1,30 +1,69 @@
# Get the abstract solid model's bounding box in space (and possibly also its children's bounding boxes to get a bounding volume hierarchy)
# Get the abstract solid model's bounding box in space (and possibly also its
# children's bounding boxes to get a bounding volume hierarchy)
# Bounding boxes are axis aligned for now for simiplicity's sake

compileASMBounds = (abstractSolidModel) ->
dispatch =
scene: (node) ->
sphere: (node) ->
cylinder: (node) ->
intersect: (node) ->
union: (node) ->
difference: (node) ->
translate: (node) ->
material: (node) ->
# Constants (enum)
INTERSECT = 0
UNION = 1

compileASMNode = (node) ->
switch typeof node
when 'object'
if dispatch[node.type]?
return dispatch[node.type] node
else
mecha.log "Unexpected node type '#{node.type}'."
return {}
else
mecha.log "Unexpected node of type '#{typeof node}'."
return {}
if abstractSolidModel.type != 'scene'
mecha.log "Expected node of type 'scene' at the root of the solid model, instead, got '#{abstractSolidModel.type}'."
return
preDispatch =
invert: (stack, node, flags) ->
flags.invert = not flags.invert
union: (stack, node, flags) ->
flags.composition.push UNION
intersect: (stack, node, flags) ->
flags.composition.push INTERSECT
default: (stack, node, flags) ->
return

compileASMNode abstractSolidModel
intersectChildren: (nodes) ->
bounds = [[-Infinity, -Infinity, -Infinity], [Infinity, Infinity, Infinity]]
for n in nodes
bounds[0][i] = Math.max n.bounds[0][i], bounds[0][i] for i in [0..2]
bounds[1][i] = Math.min n.bounds[1][i], bounds[1][i] for i in [0..2]
bounds

unionChildren: (nodes) ->
bounds = [[Infinity, Infinity, Infinity], [-Infinity, -Infinity, -Infinity]]
for n in nodes
bounds[0][i] = Math.min n.bounds[0][i], bounds[0][i] for i in [0..2]
bounds[1][i] = Math.max n.bounds[1][i], bounds[1][i] for i in [0..2]
bounds

postDispatch =
invert: (stack, node, flags) ->
flags.invert = not flags.invert
stack[0].nodes.push node
union: (stack, node, flags) ->
flags.composition.pop()
stack[0].nodes.push node
intersect: (stack, node, flags) ->
flags.composition.pop()
stack[0].nodes.push node
translate: (stack, node, flags) ->
stack[0].nodes.push node
halfspace: (stack, node, flags) ->
node.bounds = [[-Infinity, -Infinity, -Infinity], [Infinity, Infinity, Infinity]]
node.bounds[if flags.invert then 0 else 1][node.attr.axis] = node.attr.val
stack[0].nodes.push node
cylinder: (stack, node, flags) ->
node.bounds = [[-node.attr.radius, -node.attr.radius, -node.attr.radius], [node.attr.radius, node.attr.radius, node.attr.radius]]
node.bounds[0][node.attr.axis] = -Infinity
node.bounds[1][node.attr.axis] = Infinity
stack[0].nodes.push node
sphere: (stack, node, flags) ->
node.bounds = [[-node.attr.radius, -node.attr.radius, -node.attr.radius], [node.attr.radius, node.attr.radius, node.attr.radius]]
stack[0].nodes.push node
material: (stack, node, flags) ->
stack[0].nodes.push node
default: (stack, node, flags) ->
stack[0].nodes.push node

flags =
invert: false
composition: [UNION]
result = mapASM preDispatch, postDispatch, [{nodes: []}], abstractSolidModel, flags
result.flags = flags
result

1 change: 1 addition & 0 deletions src/compile.asm.generics.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ mapASM = (preDispatch, postDispatch, stack, node, flags) ->
postDispatch['default'] stack, resultNode, flags
stack.reverse()
return stack[0]

19 changes: 16 additions & 3 deletions src/compile.glsl.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ compileGLSL = (abstractSolidModel) ->
console.log "ASM:"
console.log abstractSolidModel

# Generate the fragment shader

distanceResult = glslSceneDistance abstractSolidModel

# TEMPORARY
Expand All @@ -128,13 +130,24 @@ compileGLSL = (abstractSolidModel) ->
mecha.logInternalError 'GLSL Compiler: Expected exactly one result node from id compiler.'
return ""

program = prefix +
fragmentShader = prefix +
(glslLibrary.compile distanceResult.flags.glslFunctions) +
(sceneDist distanceResult.flags.glslPrelude.code, distanceResult.nodes[0].code) +
sceneNormal +
(sceneId idResult.flags.glslPrelude.code, idResult.nodes[0].code) +
(sceneMaterial idResult.flags.materials) +
main
console.log program
return program
console.log fragmentShader

# Generate the vertex shader

boundsResult = compileASMBounds abstractSolidModel

# TEMPORARY
console.log "Bounds Result:"
console.log boundsResult

# TODO: vertexShader = ...

return fragmentShader

128 changes: 97 additions & 31 deletions static/lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,37 +379,100 @@
], node, flags);
};
compileASMBounds = function(abstractSolidModel) {
var compileASMNode, dispatch;
dispatch = {
scene: function(node) {},
sphere: function(node) {},
cylinder: function(node) {},
intersect: function(node) {},
union: function(node) {},
difference: function(node) {},
translate: function(node) {},
material: function(node) {}
var INTERSECT, UNION, flags, postDispatch, preDispatch, result;
INTERSECT = 0;
UNION = 1;
preDispatch = {
invert: function(stack, node, flags) {
return flags.invert = !flags.invert;
},
union: function(stack, node, flags) {
return flags.composition.push(UNION);
},
intersect: function(stack, node, flags) {
return flags.composition.push(INTERSECT);
},
"default": function(stack, node, flags) {}
};
compileASMNode = function(node) {
switch (typeof node) {
case 'object':
if (dispatch[node.type] != null) {
return dispatch[node.type](node);
} else {
mecha.log("Unexpected node type '" + node.type + "'.");
return {};
({
intersectChildren: function(nodes) {
var bounds, i, n, _i, _len;
bounds = [[-Infinity, -Infinity, -Infinity], [Infinity, Infinity, Infinity]];
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
n = nodes[_i];
for (i = 0; i <= 2; i++) {
bounds[0][i] = Math.max(n.bounds[0][i], bounds[0][i]);
}
break;
default:
mecha.log("Unexpected node of type '" + (typeof node) + "'.");
return {};
for (i = 0; i <= 2; i++) {
bounds[1][i] = Math.min(n.bounds[1][i], bounds[1][i]);
}
}
return bounds;
},
unionChildren: function(nodes) {
var bounds, i, n, _i, _len;
bounds = [[Infinity, Infinity, Infinity], [-Infinity, -Infinity, -Infinity]];
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
n = nodes[_i];
for (i = 0; i <= 2; i++) {
bounds[0][i] = Math.min(n.bounds[0][i], bounds[0][i]);
}
for (i = 0; i <= 2; i++) {
bounds[1][i] = Math.max(n.bounds[1][i], bounds[1][i]);
}
}
return bounds;
}
});
postDispatch = {
invert: function(stack, node, flags) {
flags.invert = !flags.invert;
return stack[0].nodes.push(node);
},
union: function(stack, node, flags) {
flags.composition.pop();
return stack[0].nodes.push(node);
},
intersect: function(stack, node, flags) {
flags.composition.pop();
return stack[0].nodes.push(node);
},
translate: function(stack, node, flags) {
return stack[0].nodes.push(node);
},
halfspace: function(stack, node, flags) {
node.bounds = [[-Infinity, -Infinity, -Infinity], [Infinity, Infinity, Infinity]];
node.bounds[flags.invert ? 0 : 1][node.attr.axis] = node.attr.val;
return stack[0].nodes.push(node);
},
cylinder: function(stack, node, flags) {
node.bounds = [[-node.attr.radius, -node.attr.radius, -node.attr.radius], [node.attr.radius, node.attr.radius, node.attr.radius]];
node.bounds[0][node.attr.axis] = -Infinity;
node.bounds[1][node.attr.axis] = Infinity;
return stack[0].nodes.push(node);
},
sphere: function(stack, node, flags) {
node.bounds = [[-node.attr.radius, -node.attr.radius, -node.attr.radius], [node.attr.radius, node.attr.radius, node.attr.radius]];
return stack[0].nodes.push(node);
},
material: function(stack, node, flags) {
return stack[0].nodes.push(node);
},
"default": function(stack, node, flags) {
return stack[0].nodes.push(node);
}
};
if (abstractSolidModel.type !== 'scene') {
mecha.log("Expected node of type 'scene' at the root of the solid model, instead, got '" + abstractSolidModel.type + "'.");
return;
}
return compileASMNode(abstractSolidModel);
flags = {
invert: false,
composition: [UNION]
};
result = mapASM(preDispatch, postDispatch, [
{
nodes: []
}
], abstractSolidModel, flags);
result.flags = flags;
return result;
};
compileASM = function(concreteSolidModel) {
var compileASMNode, dispatch;
Expand Down Expand Up @@ -981,7 +1044,7 @@
return result;
}));
compileGLSL = function(abstractSolidModel) {
var distanceResult, idResult, main, prefix, program, rayDirection, rayOrigin, sceneDist, sceneId, sceneMaterial, sceneNormal, sceneRayDist, uniforms;
var boundsResult, distanceResult, fragmentShader, idResult, main, prefix, rayDirection, rayOrigin, sceneDist, sceneId, sceneMaterial, sceneNormal, sceneRayDist, uniforms;
rayOrigin = 'ro';
rayDirection = 'rd';
prefix = '#ifdef GL_ES\n precision highp float;\n#endif\nuniform vec3 SCENEJS_uEye; // World-space eye position\nvarying vec3 SCENEJS_vEyeVec; // Output world-space eye vector\nvarying vec4 SCENEJS_vWorldVertex; // Varying for fragment clip or world pos hook\n';
Expand Down Expand Up @@ -1038,9 +1101,12 @@
mecha.logInternalError('GLSL Compiler: Expected exactly one result node from id compiler.');
return "";
}
program = prefix + (glslLibrary.compile(distanceResult.flags.glslFunctions)) + (sceneDist(distanceResult.flags.glslPrelude.code, distanceResult.nodes[0].code)) + sceneNormal + (sceneId(idResult.flags.glslPrelude.code, idResult.nodes[0].code)) + (sceneMaterial(idResult.flags.materials)) + main;
console.log(program);
return program;
fragmentShader = prefix + (glslLibrary.compile(distanceResult.flags.glslFunctions)) + (sceneDist(distanceResult.flags.glslPrelude.code, distanceResult.nodes[0].code)) + sceneNormal + (sceneId(idResult.flags.glslPrelude.code, idResult.nodes[0].code)) + (sceneMaterial(idResult.flags.materials)) + main;
console.log(fragmentShader);
boundsResult = compileASMBounds(abstractSolidModel);
console.log("Bounds Result:");
console.log(boundsResult);
return fragmentShader;
};
constants = {
canvas: {
Expand Down
Loading

0 comments on commit ad12d56

Please sign in to comment.