Back to Content

Creating 3D geometry using JavaScript - Tutorial

You can generate new geometry from scratch in Coppercube, using scripting. This is possible not only in the editor, but also in the Windows .exe and Mac OS X .app target, during runtime, and can be very useful. It is actually very easy and this short tutorial shows how:

The resulting generated geometry

It works like this: For every geometry in CopperCube you have two buffers: one which holds the vertices with position, color, etc. And another buffer which holds indices to those vertices. So if you have for example 4 vertices:
 |     |
 |     |

Then for creating a rectangle, you would need to make two triangles out of this:

 |   / |
 | /   |

So, in the index buffer, you will need to store the two triangles, 0-1-2 and 1-3-2. So the index buffer will look like this;:

For adding a vertex to the vertex buffer, there is the function ccbAddMeshBufferVertex() and for adding an index, use the function ccbAddMeshBufferIndex().

As example code, we let the user select a 3D object in the editor, and replace all of its geometry with a rectangle:

// use the currently selected node in the editor
var meshnode = editorGetSelectedSceneNode(); 
var bufferCount = ccbGetSceneNodeMeshBufferCount(meshnode);

if (bufferCount == 0)
  alert('The selected node has no 3D geometry.');
	// get old texture of that node
	var oldTexture = ccbGetSceneNodeMaterialProperty(meshnode, 0, "Texture1");
	// remove all mesh buffers holding geometry, because we want to replace its geometry with a totally new one
	for (var i=0; i<bufferCount; ++i)
		ccbRemoveMeshBuffer(meshnode, 0);
	// add new buffer
	// disable dynamic lighting and set a texture
	ccbSetSceneNodeMaterialProperty(meshnode, 0, 'Lighting', false);
	ccbSetSceneNodeMaterialProperty(meshnode, 0, "Texture1", oldTexture);
	// add 4 vertices
	ccbAddMeshBufferVertex(meshnode, 0, new vector3d(0,10,0));
	ccbAddMeshBufferVertex(meshnode, 0, new vector3d(10,10,0));
	ccbAddMeshBufferVertex(meshnode, 0, new vector3d(0,0,0));
	ccbAddMeshBufferVertex(meshnode, 0, new vector3d(10,0,0));
	// set their colors
	ccbSetMeshBufferVertexColor(meshnode, 0, 0, 0x77400000);
	ccbSetMeshBufferVertexColor(meshnode, 0, 1, 0x77400000);
	ccbSetMeshBufferVertexColor(meshnode, 0, 2, 0x77400000);
	ccbSetMeshBufferVertexColor(meshnode, 0, 3, 0x77400000);
	// set texture coordinate
	ccbSetMeshBufferVertexTextureCoord(meshnode, 0, 0, new vector3d(0,1,0));
	ccbSetMeshBufferVertexTextureCoord(meshnode, 0, 1, new vector3d(1,1,0));
	ccbSetMeshBufferVertexTextureCoord(meshnode, 0, 2, new vector3d(0,0,0));
	ccbSetMeshBufferVertexTextureCoord(meshnode, 0, 3, new vector3d(1,0,0));
	// add 6 indices, to create 2 triangles from this.
	// note that the order is important. If you are adding the indices
	// 0,1,2, you create a triangle facing into forward direction,
	// if you add it with 0,2,1, it will face into the opposite direction.
	ccbAddMeshBufferIndex(meshnode, 0, 0);
	ccbAddMeshBufferIndex(meshnode, 0, 1);
	ccbAddMeshBufferIndex(meshnode, 0, 2);
	ccbAddMeshBufferIndex(meshnode, 0, 1);
	ccbAddMeshBufferIndex(meshnode, 0, 3);
	ccbAddMeshBufferIndex(meshnode, 0, 2);	
	// update the bounding box of the node

For trying this, just open the scripting window (View -> Scripting Window), clear all the text in it, paste this text into there, and click 'execute'. Be sure to select a 3d object before.