/**
* GeometricPrimitive renders a primitive
* @class GeometricPrimitive
* @constructor
* @param {String} object to configure from
*/
function GeometricPrimitive( o )
{
this.enabled = true;
this.size = 10;
this.subdivisions = 10;
this.point_size = 0.1;
this._geometry = GeometricPrimitive.CUBE;
this._primitive = -1;
this.align_z = false;
if(o)
this.configure(o);
}
Object.defineProperty( GeometricPrimitive.prototype, 'primitive', {
get: function() { return this._primitive; },
set: function(v) {
v = (v === undefined || v === null ? -1 : v|0);
if(v != -1 && v != 0 && v!= 1 && v!= 4 && v!= 10)
return;
this._primitive = v;
},
enumerable: true
});
Object.defineProperty( GeometricPrimitive.prototype, 'geometry', {
get: function() { return this._geometry; },
set: function(v) {
v = (v === undefined || v === null ? -1 : v|0);
if(v < 0 || v > 7)
return;
this._geometry = v;
},
enumerable: true
});
GeometricPrimitive.CUBE = 1;
GeometricPrimitive.PLANE = 2;
GeometricPrimitive.CYLINDER = 3;
GeometricPrimitive.SPHERE = 4;
GeometricPrimitive.CIRCLE = 5;
GeometricPrimitive.HEMISPHERE = 6;
GeometricPrimitive.ICOSAHEDRON = 7;
//Warning : if you add more primitives, be careful with the setter, it doesnt allow values bigger than 7
GeometricPrimitive.icon = "mini-icon-cube.png";
GeometricPrimitive["@geometry"] = { type:"enum", values: {"Cube":GeometricPrimitive.CUBE, "Plane": GeometricPrimitive.PLANE, "Cylinder":GeometricPrimitive.CYLINDER, "Sphere":GeometricPrimitive.SPHERE, "Icosahedron":GeometricPrimitive.ICOSAHEDRON, "Circle":GeometricPrimitive.CIRCLE, "Hemisphere":GeometricPrimitive.HEMISPHERE }};
GeometricPrimitive["@primitive"] = {widget:"enum", values: {"Default":-1, "Points": 0, "Lines":1, "Triangles":4, "Wireframe":10 }};
GeometricPrimitive["@subdivisions"] = { type:"number", step:1, min:0 };
GeometricPrimitive["@point_size"] = { type:"number", step:0.001 };
//we bind to onAddedToNode because the event is triggered per node so we know which RIs belong to which node
GeometricPrimitive.prototype.onAddedToNode = function( node )
{
LEvent.bind( node, "collectRenderInstances", this.onCollectInstances, this);
}
GeometricPrimitive.prototype.onRemovedFromNode = function( node )
{
LEvent.unbind( node, "collectRenderInstances", this.onCollectInstances, this);
}
GeometricPrimitive.prototype.updateMesh = function()
{
var subdivisions = Math.max(0,this.subdivisions|0);
var key = "" + this.geometry + "|" + this.size + "|" + subdivisions + "|" + this.align_z;
switch (this.geometry)
{
case GeometricPrimitive.CUBE:
this._mesh = GL.Mesh.cube({size: this.size, normals:true,coords:true});
break;
case GeometricPrimitive.PLANE:
this._mesh = GL.Mesh.plane({size: this.size, detail: subdivisions, xz: this.align_z, normals:true,coords:true});
break;
case GeometricPrimitive.CYLINDER:
this._mesh = GL.Mesh.cylinder({size: this.size, subdivisions: subdivisions, normals:true,coords:true});
break;
case GeometricPrimitive.SPHERE:
this._mesh = GL.Mesh.sphere({size: this.size, "long":subdivisions, lat: subdivisions, normals:true,coords:true});
break;
case GeometricPrimitive.CIRCLE:
this._mesh = GL.Mesh.circle({size: this.size, slices:subdivisions, xz: this.align_z, normals:true, coords:true});
break;
case GeometricPrimitive.HEMISPHERE:
this._mesh = GL.Mesh.sphere({size: this.size, slices:subdivisions, xz: this.align_z, normals:true, coords:true, hemi: true});
break;
case GeometricPrimitive.ICOSAHEDRON:
this._mesh = GL.Mesh.icosahedron({size: this.size, subdivisions:subdivisions });
break;
}
this._key = key;
}
//GeometricPrimitive.prototype.getRenderInstance = function()
GeometricPrimitive.prototype.onCollectInstances = function(e, instances)
{
if(!this.enabled)
return;
//if(this.size == 0) return;
var mesh = null;
if(!this._root)
return;
var subdivisions = Math.max(0,this.subdivisions|0);
var key = "" + this.geometry + "|" + this.size + "|" + subdivisions + "|" + this.align_z;
if(!this._mesh || this._key != key)
this.updateMesh();
var RI = this._render_instance;
if(!RI)
this._render_instance = RI = new LS.RenderInstance(this._root, this);
if(this._root.transform)
this._root.transform.getGlobalMatrix( RI.matrix );
RI.setMatrix( RI.matrix ); //force normal
//mat4.multiplyVec3( RI.center, RI.matrix, vec3.create() );
mat4.getTranslation( RI.center, RI.matrix );
RI.setMesh( this._mesh, this.primitive );
this._root.mesh = this._mesh;
RI.setMaterial( this.material || this._root.getMaterial() );
if(this.primitive == gl.POINTS)
{
RI.uniforms.u_point_size = this.point_size;
RI.query.macros["USE_POINTS"] = "";
}
instances.push(RI);
}
LS.registerComponent( GeometricPrimitive );