1 /**
  2  * potree.js 
  3  * http://potree.org
  4  *
  5  * Copyright 2012, Markus Sch�tz
  6  * Licensed under the GPL Version 2 or later.
  7  * - http://potree.org/wp/?page_id=7
  8  * - http://www.gnu.org/licenses/gpl-3.0.html
  9  *
 10  */
 11 
 12 /**
 13  * @class Loads mno files and returns a PointcloudOctree
 14  * for a description of the mno binary file format, read mnoFileFormat.txt
 15  * 
 16  * @author Markus Sch�tz
 17  */
 18 function POCLoader(){
 19 	
 20 }
 21  
 22 /**
 23  * @return a point cloud octree with the root node data loaded. 
 24  * loading of descendants happens asynchronously when they're needed
 25  * 
 26  * @param file the xml mno file
 27  * @param loadingFinishedListener executed after loading the binary has been finished
 28  */
 29 POCLoader.load = function load(file) {
 30 	try{
 31 		var pco = new PointcloudOctree();
 32 		var xhr = new XMLHttpRequest();
 33 		xhr.open('GET', file, false);
 34 		xhr.send(null);
 35 		if(xhr.status == 200 || xhr.status == 0){
 36 			var fMno = JSON.parse(xhr.responseText);
 37 			
 38 			pco.octreeDir = file + "/../data";
 39 			var pointAttributes = POCLoader.loadPointAttributes(fMno);
 40 			pco.setPointAttributes(pointAttributes);
 41 			
 42 			{ // load Root
 43 				var mRoot = new PointcloudOctreeNode("r", pco);
 44 				var aabb = new AABB();
 45 				aabb.setDimensionByMinMax(
 46 						[ fMno.boundingBox.lx, fMno.boundingBox.ly, fMno.boundingBox.lz ],  
 47 						[ fMno.boundingBox.ux, fMno.boundingBox.uy, fMno.boundingBox.uz ]);
 48 				mRoot.setAABB(aabb);
 49 				mRoot.points = fMno.hierarchy[0][1];
 50 				pco.rootNode = mRoot;
 51 			}
 52 			
 53 			// load remaining hierarchy
 54 			for( var i = 1; i < fMno.hierarchy.length; i++){
 55 				var nodeName = fMno.hierarchy[i][0];
 56 				var points = fMno.hierarchy[i][1];
 57 				var mNode = new PointcloudOctreeNode(nodeName, pco);
 58 				mNode.points = points;
 59 				pco.rootNode.addChild(mNode);
 60 				var childIndex = mNode.name.charAt(mNode.name.length-1);
 61 				var childAABB = POCLoader.createChildAABB(mNode.parent.aabb, childIndex);
 62 				mNode.setAABB(childAABB);
 63 			}
 64 			
 65 		}
 66 		
 67 		var pcoNode = new PointcloudOctreeSceneNode(pco);
 68 		return pcoNode;
 69 	}catch(e){
 70 		Logger.error("loading failed: '" + file + "'");
 71 		Logger.error(e);
 72 	}
 73 };
 74 
 75 POCLoader.loadPointAttributes = function(mno){
 76 	
 77 	var fpa = mno.pointAttributes;
 78 	var pa = new PointAttributes();
 79 	
 80 	for(var i = 0; i < fpa.length; i++){   
 81 		var pointAttribute = PointAttribute[fpa[i]];
 82 		pa.add(pointAttribute);
 83 	}                                                                     
 84 	
 85 	return pa;
 86 //	var fpa = mno.pointAttributes;
 87 //	var pa = {
 88 //		'numAttributes' : fpa.length,
 89 //		'bytesPerPoint' : 0,
 90 //		'attributes' : {}
 91 //	};
 92 //	
 93 //	for(var i = 0; i < fpa.length; i++){
 94 //		var pointAttribute = PointAttributes[fpa[i]];
 95 //		pa.attributes[i] = pointAttribute; 
 96 //		var bytes = pointAttribute.type.size * pointAttribute.numElements;
 97 //		pa.bytesPerPoint += bytes;
 98 //	}
 99 //	
100 //	return pa;
101 };
102 
103 
104 /**
105  * creates an aabb that covers the area of the childnode at childIndex
106  * 
107  * @param aabb aabb of the parent
108  * @param childIndex index of the childs region
109  * @returns {AABB}
110  */
111 POCLoader.createChildAABB = function(aabb, childIndex){
112 	var min = aabb.objectSpaceMin;
113 	var max = aabb.objectSpaceMax;
114 	var caabb = new AABB();
115 	// (aabb.max - aabb.minPos) * 0.5
116 	var dHalfLength = V3.scale(V3.sub(max,min), 0.5);
117 	var xHalfLength = [ dHalfLength[0], 0, 0 ];
118 	var yHalfLength = [ 0, dHalfLength[1], 0 ];
119 	var zHalfLength = [ 0, 0, dHalfLength[2] ];
120 
121 	{
122 		var cmin = min;
123 		// max = min + (aabb.max - aabb.min) * 0.5;
124 		var cmax = V3.add(min, dHalfLength);
125 		var caabb = new AABB();
126 		caabb.setDimensionByMinMax(cmin, cmax);
127 	}
128 
129 	if (childIndex == 1) {
130 		var min = V3.add(caabb.min, zHalfLength);
131 		var max = V3.add(caabb.max, zHalfLength);
132 		caabb.setDimensionByMinMax(min, max);
133 		caabb.setColor([0.0, 0.0, 1.0, 1.0]);
134 	}else if (childIndex == 3) {
135 		var min = V3.add(V3.add(caabb.min, zHalfLength), yHalfLength);
136 		var max = V3.add(V3.add(caabb.max, zHalfLength), yHalfLength);
137 		caabb.setDimensionByMinMax(min, max);
138 		caabb.setColor([1.0, 1.0, 0.0, 1.0]);
139 	}else if (childIndex == 0) {
140 		caabb.setColor([1.0, 0.0, 0.0, 1.0]);
141 	}else if (childIndex == 2) {
142 		var min = V3.add(caabb.min, yHalfLength);
143 		var max = V3.add(caabb.max, yHalfLength);
144 		caabb.setDimensionByMinMax(min, max);
145 		caabb.setColor([0.0, 1.0, 0.0, 1.0]);
146 	}else if (childIndex == 5) {
147 		var min = V3.add(V3.add(caabb.min, zHalfLength), xHalfLength);
148 		var max = V3.add(V3.add(caabb.max, zHalfLength), xHalfLength);
149 		caabb.setDimensionByMinMax(min, max);
150 		caabb.setColor([1.0, 1.0, 1.0, 1.0]);
151 	}else if (childIndex == 7) {
152 		var min = V3.add(caabb.min, dHalfLength);
153 		var max = V3.add(caabb.max, dHalfLength);
154 		caabb.setDimensionByMinMax(min, max);
155 		caabb.setColor([0.0, 0.0, 0.0, 1.0]);
156 	}else if (childIndex == 4) {
157 		var min = V3.add(caabb.min, xHalfLength);
158 		var max = V3.add(caabb.max, xHalfLength);
159 		caabb.setDimensionByMinMax(min, max);
160 		caabb.setColor([1.0, 0.0, 1.0, 1.0]);
161 	}else if (childIndex == 6) {
162 		var min = V3.add(V3.add(caabb.min, xHalfLength), yHalfLength);
163 		var max = V3.add(V3.add(caabb.max, xHalfLength), yHalfLength);
164 		caabb.setDimensionByMinMax(min, max);
165 		caabb.setColor([0.0, 1.0, 1.0, 1.0]);
166 	}
167 	
168 	return caabb;
169 }
170 
171 
172