Namide

Merge cubes with Minko

Merges a lot of cubes to create an only mesh. The best is to use a minimum of vertices for a maximum of indexes. A only mesh with a lot of indices is better optimized versus a lot of meshs with little indices.

Merge cube, example

The baby hammer shark and the Great Barrier Reef

I have write this script during the Mini Ludum Dare #46 (November 2nd/3rd 2013).

Game: The baby hammer shark and the Great Barrier Reef
Language: ActionScript 3 (FlashPlayer 11.7)
3D engine: Minko 2.2
cubes merged
Example of merged cubes

Merge the cubes

To generate a procedural world, an algorithm merges the cubes to create models without texture. Each vertex of model has two data formats:

These meshes are very light, which is good for manipulations and loading into the GPU. The 3D render engine used is Minko.

You must to add the library Minko 2.2 to use this class.

package sharkzel.gameplay.factories 
{
	
	import aerys.minko.render.geometry.Geometry;
	import aerys.minko.render.geometry.stream.format.VertexFormat;
	import aerys.minko.render.geometry.stream.IndexStream;
	import aerys.minko.render.geometry.stream.StreamUsage;
	import aerys.minko.render.geometry.stream.VertexStream;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Namide
	 */
	public class Modeler 
	{
		
		protected static var _CUBE_INDICES:Vector. = Vector.( [0, 1, 2, 0, 3, 1, 4, 5, 6, 7, 5, 4, 5, 3, 0, 3, 5, 7, 1, 4, 2, 4, 6, 2, 4, 3, 7, 3, 4, 1, 5, 0, 2, 2, 6, 5] );
		protected static var _CUBE_VERTICES:Vector. = Vector.( [1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1] );
		
		protected var _modelIndices:Vector.;
		protected var _modelVertices:Vector.;
		
		protected var _memoryidIndice:uint = 0;
		protected var _memoryIndices:Object;
		
		protected var _color:Vector3D;
		protected var _colorStep:Number = 0.1;
		
		protected var _center:Vector3D;
		
		
		public function Modeler( color:Vector3D, center:Vector3D ) 
		{
			_center = ( center == null ) ? new Vector3D() : center;
			
			_modelIndices = new Vector.( 0, false );
			_modelVertices = new Vector.( 0, false );
			_memoryIndices = { };
			_color = color;
			_color.x -= _colorStep * 0.5;
			_color.y -= _colorStep * 0.5;
			_color.z -= _colorStep * 0.5;
		}
		
		public function addCube( x:Number, y:Number, z:Number, w:Number = 1, h:Number = 1, p:Number = 1, color:Vector3D = null ):Modeler
		{
			var id:String;
			var i3:int, i5:int;
			var xTemp:Number, yTemp:Number, zTemp:Number;
			var r:Number, g:Number, b:Number;
			
			for ( var i:int = 0; i < _CUBE_INDICES.length; i++ )
			{
				
				i3 = _CUBE_INDICES[i] * 3;
				i5 = _CUBE_INDICES[i] * 5;
				
				xTemp = _CUBE_VERTICES[ i3 ] * w + x - _center.x;
				yTemp = _CUBE_VERTICES[ i3 + 1 ] * h + y - _center.y;
				zTemp = _CUBE_VERTICES[ i3 + 2 ] * p + z - _center.z;
				
				id = xTemp + "," + yTemp + "," + zTemp;
				
				if ( _memoryIndices[id] == null )
				{
					_memoryIndices[id] = _memoryidIndice;
					_modelIndices[_modelIndices.length] = _memoryidIndice;
					
					if ( color == null )
					{
						r = _color.x + Math.random() * _colorStep;
						g = _color.y + Math.random() * _colorStep;
						b = _color.z + Math.random() * _colorStep;
					}
					else
					{
						r = color.x;
						g = color.y;
						b = color.z;
					}
					
					_modelVertices.push( xTemp, yTemp, zTemp, r, g, b );
					_memoryidIndice++;
				}
				else
				{
					_modelIndices[_modelIndices.length] = _memoryIndices[id];
					
				}
				
			}
			
			
			return this;
		}
		
		public function getGeometry():Geometry
		{
			var geom:Geometry = new Geometry( 	Vector.([ VertexStream.fromVector( StreamUsage.STATIC, VertexFormat.XYZ_RGB, _modelVertices ) ]),
												IndexStream.fromVector( StreamUsage.STATIC, _modelIndices )		);
			
			return geom;
		}
		
	}

}