Selaa lähdekoodia

World: Add support for arbitrary transforms on world models

trethaller 7 vuotta sitten
vanhempi
commit
ebc5cb4574
2 muutettua tiedostoa jossa 76 lisäystä ja 89 poistoa
  1. 46 57
      h3d/prim/BigPrimitive.hx
  2. 30 32
      h3d/scene/World.hx

+ 46 - 57
h3d/prim/BigPrimitive.hx

@@ -181,9 +181,10 @@ class BigPrimitive extends Primitive {
 		The buffer can have more stride than the BigPrimitive, but not less.
 		The buffer can have more stride than the BigPrimitive, but not less.
 		It is assumed that the buffer contains [X,Y,Z,NX,NY,NZ,U,V,R,G,B] (depending on his stride) so the different offsets are applied to the corresponding components.
 		It is assumed that the buffer contains [X,Y,Z,NX,NY,NZ,U,V,R,G,B] (depending on his stride) so the different offsets are applied to the corresponding components.
 		However if the stride is 5, we assume [X,Y,Z,U,V]
 		However if the stride is 5, we assume [X,Y,Z,U,V]
+		If mat is not null, it overrides dx, dy, dz, rotation, scale
 	**/
 	**/
 	@:noDebug
 	@:noDebug
-	public function addSub( buf : hxd.FloatBuffer, idx : hxd.IndexBuffer, startVert, startTri, nvert, triCount, dx : Float = 0. , dy : Float = 0., dz : Float = 0., rotation = 0., scale = 1., stride = -1, deltaU = 0., deltaV = 0., color = 1. ) {
+	public function addSub( buf : hxd.FloatBuffer, idx : hxd.IndexBuffer, startVert, startTri, nvert, triCount, dx : Float = 0. , dy : Float = 0., dz : Float = 0., rotation = 0., scale = 1., stride = -1, deltaU = 0., deltaV = 0., color = 1., mat : h3d.Matrix = null) {
 		if( stride < 0 ) stride = this.stride;
 		if( stride < 0 ) stride = this.stride;
 		if( stride < this.stride ) throw "only stride >= " + this.stride+" allowed";
 		if( stride < this.stride ) throw "only stride >= " + this.stride+" allowed";
 		begin(nvert, triCount*3);
 		begin(nvert, triCount*3);
@@ -197,78 +198,66 @@ class BigPrimitive extends Primitive {
 		var tmpBuf : hl.BytesAccess<hxd.impl.Float32> = hl.Bytes.getArray(tmpBuf.getNative());
 		var tmpBuf : hl.BytesAccess<hxd.impl.Float32> = hl.Bytes.getArray(tmpBuf.getNative());
 		#end
 		#end
 		for( i in 0...nvert ) {
 		for( i in 0...nvert ) {
+			inline function add(v) tmpBuf[pos++] = v;
+			
 			var p = (i + startVert) * stride;
 			var p = (i + startVert) * stride;
 			var x = buf[p++];
 			var x = buf[p++];
 			var y = buf[p++];
 			var y = buf[p++];
 			var z = buf[p++];
 			var z = buf[p++];
-			var tx = (x * cr - y * sr) * scale;
-			var ty = (x * sr + y * cr) * scale;
 
 
-			inline function add(v) tmpBuf[pos++] = v;
+			if(mat != null) {
+				var pt = new h3d.col.Point(x, y, z);
+				pt.transform(mat);
+				add(pt.x);
+				add(pt.y);
+				add(pt.z);
+				bounds.addPos(pt.x, pt.y, pt.z);
+			}
+			else {
+				var tx = (x * cr - y * sr) * scale;
+				var ty = (x * sr + y * cr) * scale;
+				var vx = dx + tx;
+				var vy = dy + ty;
+				var vz = dz + z * scale;
+				add(vx);
+				add(vy);
+				add(vz);
+				bounds.addPos(vx, vy, vz);
+			}
+
+			if(this.stride >= 6) {
+				var nx = buf[p++];
+				var ny = buf[p++];
+				var nz = buf[p++];
 
 
-			var vx = dx + tx;
-			var vy = dy + ty;
-			var vz = dz + z * scale;
-			add(vx);
-			add(vy);
-			add(vz);
-			bounds.addPos(vx, vy, vz);
+				if(mat != null) {
+					var pt = new h3d.col.Point(nx, ny, nz);
+					pt.transform3x3(mat);
+					pt.normalize();
+					add(pt.x);
+					add(pt.y);
+					add(pt.z);
+				}
+				else {
+					var tnx = nx * cr - ny * sr;
+					var tny = nx * sr + ny * cr;
+					add(tnx);
+					add(tny);
+					add(nz);
+				}
+			}
 
 
 			switch( this.stride ) {
 			switch( this.stride ) {
 			case 3:
 			case 3:
 				continue;
 				continue;
-			case 4:
-				add(buf[p++]);
-			case 5:
-				// assume no normal
-				add(buf[p++] + deltaU);
-				add(buf[p++] + deltaV);
-			case 6:
-				var nx = buf[p++];
-				var ny = buf[p++];
-				var nz = buf[p++];
-				var tnx = nx * cr - ny * sr;
-				var tny = nx * sr + ny * cr;
-				add(tnx);
-				add(tny);
-				add(nz);
-			case 7:
-				var nx = buf[p++];
-				var ny = buf[p++];
-				var nz = buf[p++];
-				var tnx = nx * cr - ny * sr;
-				var tny = nx * sr + ny * cr;
-				add(tnx);
-				add(tny);
-				add(nz);
+			case 4, 7:
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaU);
-			case 8, 9, 10:
-				var nx = buf[p++];
-				var ny = buf[p++];
-				var nz = buf[p++];
-				var tnx = nx * cr - ny * sr;
-				var tny = nx * sr + ny * cr;
-				add(tnx);
-				add(tny);
-				add(nz);
-
-				// UV
+			case 5, 8, 9, 10:
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaV);
 				add(buf[p++] + deltaV);
-
 				for( i in 8...this.stride )
 				for( i in 8...this.stride )
 					add(buf[p++]);
 					add(buf[p++]);
-
 			default:
 			default:
-				var nx = buf[p++];
-				var ny = buf[p++];
-				var nz = buf[p++];
-				var tnx = nx * cr - ny * sr;
-				var tny = nx * sr + ny * cr;
-				add(tnx);
-				add(tny);
-				add(nz);
-
 				// UV
 				// UV
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaV);
 				add(buf[p++] + deltaV);

+ 30 - 32
h3d/scene/World.hx

@@ -2,18 +2,12 @@ package h3d.scene;
 
 
 class WorldElement {
 class WorldElement {
 	public var model : WorldModel;
 	public var model : WorldModel;
-	public var x : Float;
-	public var y : Float;
-	public var z : Float;
-	public var scale : Float;
-	public var rotation : Float;
-	public function new( model, x, y, z, scale = 1., rotation = 0. ) {
+	public var transform : h3d.Matrix;
+	public var optimized : Bool;
+	public function new( model, mat, optimized ) {
 		this.model = model;
 		this.model = model;
-		this.x = x;
-		this.y = y;
-		this.z = z;
-		this.scale = scale;
-		this.rotation = rotation;
+		this.transform = mat;
+		this.optimized = optimized;
 	}
 	}
 }
 }
 
 
@@ -377,7 +371,15 @@ class World extends Object {
 					initMaterial(b, g.m);
 					initMaterial(b, g.m);
 				}
 				}
 				var p = Std.instance(b.primitive, h3d.prim.BigPrimitive);
 				var p = Std.instance(b.primitive, h3d.prim.BigPrimitive);
-				p.addSub(model.buf, model.idx, g.startVertex, Std.int(g.startIndex / 3), g.vertexCount, Std.int(g.indexCount / 3), e.x, e.y, e.z, e.rotation, e.scale, model.stride);
+
+				if(e.optimized) {
+					var m = e.transform;
+					var scale = m._33;
+					var rotZ = hxd.Math.atan2(m._12 / scale, m._11 / scale);
+					p.addSub(model.buf, model.idx, g.startVertex, Std.int(g.startIndex / 3), g.vertexCount, Std.int(g.indexCount / 3), m.tx, m.ty, m.tz, rotZ, scale, model.stride, 0., 0., 1., null);
+				}
+				else
+					p.addSub(model.buf, model.idx, g.startVertex, Std.int(g.startIndex / 3), g.vertexCount, Std.int(g.indexCount / 3), 0., 0., 0., 0., 0., model.stride, 0., 0., 1., e.transform);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -392,24 +394,10 @@ class World extends Object {
 		c.buffers = new Map();
 		c.buffers = new Map();
 	}
 	}
 
 
-	function updateChunkBounds(c : WorldChunk, model : WorldModel, x : Float, y : Float, z : Float, rotation : Float, scale : Float) {
-		var cosR = Math.cos(rotation);
-		var sinR = Math.sin(rotation);
-
-		inline function addPoint(dx:Float, dy:Float, dz:Float) {
-			var tx = dx * cosR - dy * sinR;
-			var ty = dx * sinR + dy * cosR;
-			c.bounds.addPos(tx * scale + x, ty * scale + y, dz * scale + z);
-		}
-
-		addPoint(model.bounds.xMin, model.bounds.yMin, model.bounds.zMin);
-		addPoint(model.bounds.xMin, model.bounds.yMin, model.bounds.zMax);
-		addPoint(model.bounds.xMin, model.bounds.yMax, model.bounds.zMin);
-		addPoint(model.bounds.xMin, model.bounds.yMax, model.bounds.zMax);
-		addPoint(model.bounds.xMax, model.bounds.yMin, model.bounds.zMin);
-		addPoint(model.bounds.xMax, model.bounds.yMin, model.bounds.zMax);
-		addPoint(model.bounds.xMax, model.bounds.yMax, model.bounds.zMin);
-		addPoint(model.bounds.xMax, model.bounds.yMax, model.bounds.zMax);
+	function updateChunkBounds(c : WorldChunk, model : WorldModel, mat : h3d.Matrix ) {
+		var b = model.bounds.clone();
+		b.transform(mat);
+		c.bounds.add(b);
 	}
 	}
 
 
 	function initMaterial( mesh : h3d.scene.Mesh, mat : WorldMaterial ) {
 	function initMaterial( mesh : h3d.scene.Mesh, mat : WorldMaterial ) {
@@ -460,8 +448,18 @@ class World extends Object {
 
 
 	public function add( model : WorldModel, x : Float, y : Float, z : Float, scale = 1., rotation = 0. ) {
 	public function add( model : WorldModel, x : Float, y : Float, z : Float, scale = 1., rotation = 0. ) {
 		var c = getChunk(x, y, true);
 		var c = getChunk(x, y, true);
-		c.elements.push(new WorldElement(model, x, y, z, scale, rotation));
-		updateChunkBounds(c, model, x, y, z, rotation, scale);
+		var m = new h3d.Matrix();
+		m.initScale(scale, scale, scale);
+		m.rotate(0, 0, rotation);
+		m.translate(x, y, z);
+		c.elements.push(new WorldElement(model, m, true));
+		updateChunkBounds(c, model, m);
+	}
+
+	public function add2( model : WorldModel, mat : h3d.Matrix ) {
+		var c = getChunk(mat.tx, mat.ty, true);
+		c.elements.push(new WorldElement(model, mat, false));
+		updateChunkBounds(c, model, mat);
 	}
 	}
 
 
 	override function syncRec(ctx:RenderContext) {
 	override function syncRec(ctx:RenderContext) {