Explorar o código

World: Add support for arbitrary transforms on world models

trethaller %!s(int64=7) %!d(string=hai) anos
pai
achega
ebc5cb4574
Modificáronse 2 ficheiros con 76 adicións e 89 borrados
  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.
 		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]
+		If mat is not null, it overrides dx, dy, dz, rotation, scale
 	**/
 	@: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 < this.stride ) throw "only stride >= " + this.stride+" allowed";
 		begin(nvert, triCount*3);
@@ -197,78 +198,66 @@ class BigPrimitive extends Primitive {
 		var tmpBuf : hl.BytesAccess<hxd.impl.Float32> = hl.Bytes.getArray(tmpBuf.getNative());
 		#end
 		for( i in 0...nvert ) {
+			inline function add(v) tmpBuf[pos++] = v;
+			
 			var p = (i + startVert) * stride;
 			var x = buf[p++];
 			var y = 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 ) {
 			case 3:
 				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);
-			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++] + deltaV);
-
 				for( i in 8...this.stride )
 					add(buf[p++]);
-
 			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
 				add(buf[p++] + deltaU);
 				add(buf[p++] + deltaV);

+ 30 - 32
h3d/scene/World.hx

@@ -2,18 +2,12 @@ package h3d.scene;
 
 class WorldElement {
 	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.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);
 				}
 				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();
 	}
 
-	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 ) {
@@ -460,8 +448,18 @@ class World extends Object {
 
 	public function add( model : WorldModel, x : Float, y : Float, z : Float, scale = 1., rotation = 0. ) {
 		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) {