Ver código fonte

renamed Matrix.inverse() to initInverse, added Matrix.initInverse3x3, Bounds.transform3x3, Frustum.transform/3x3, Plane.transform/3x3, added Object.iterVisibleMeshes

ncannasse 8 anos atrás
pai
commit
fa0a2f063d

+ 2 - 2
h3d/Camera.hx

@@ -94,7 +94,7 @@ class Camera {
 	public function getInverseViewProj() {
 		if( minv == null ) minv = new h3d.Matrix();
 		if( needInv ) {
-			minv.inverse(m);
+			minv.initInverse(m);
 			needInv = false;
 		}
 		return minv;
@@ -109,7 +109,7 @@ class Camera {
 			miview._44 = 0;
 		}
 		if( miview._44 == 0 )
-			miview.inverse(mcam);
+			miview.initInverse(mcam);
 		return miview;
 	}
 

+ 43 - 2
h3d/Matrix.hx

@@ -325,7 +325,7 @@ class Matrix {
 	}
 
 	public inline function invert() {
-		inverse(this);
+		initInverse(this);
 	}
 
 	public inline function getDeterminant() {
@@ -366,7 +366,7 @@ class Matrix {
 		_41 *= invDet; _42 *= invDet; _43 *= invDet;
 	}
 
-	public function inverse( m : Matrix ) {
+	public function initInverse( m : Matrix ) {
 		var m11 = m._11; var m12 = m._12; var m13 = m._13; var m14 = m._14;
 		var m21 = m._21; var m22 = m._22; var m23 = m._23; var m24 = m._24;
 		var m31 = m._31; var m32 = m._32; var m33 = m._33; var m34 = m._34;
@@ -414,6 +414,47 @@ class Matrix {
 		_44 *= det;
 	}
 
+
+	public function initInverse3x3( m : Matrix ) {
+		var m11 = m._11; var m12 = m._12; var m13 = m._13;
+		var m21 = m._21; var m22 = m._22; var m23 = m._23;
+		var m31 = m._31; var m32 = m._32; var m33 = m._33;
+
+		_11 = m22 * m33 - m32 * m23;
+		_12 = -m12 * m33 + m32 * m13;
+		_13 = m12 * m23 - m22 * m13;
+		_21 = -m21 * m33 + m31 * m23;
+		_22 = m11 * m33 - m31 * m13;
+		_23 = -m11 * m23 + m21 * m13;
+		_31 = m21 * m32 - m31 * m22;
+		_32 = -m11 * m32 + m31 * m12;
+		_33 = m11 * m22 - m21 * m12;
+
+		var det = m11 * _11 + m12 * _21 + m13 * _31;
+		if(	Math.abs(det) < Math.EPSILON ) {
+			zero();
+			return;
+		}
+
+		det = 1.0 / det;
+		_11 *= det;
+		_12 *= det;
+		_13 *= det;
+		_14 = 0;
+		_21 *= det;
+		_22 *= det;
+		_23 *= det;
+		_24 = 0;
+		_31 *= det;
+		_32 *= det;
+		_33 *= det;
+		_34 = 0;
+		_41 = 0;
+		_42 = 0;
+		_43 = 0;
+		_44 = 1;
+	}
+
 	public function transpose() {
 		var tmp;
 		tmp = _12; _12 = _21; _21 = tmp;

+ 33 - 3
h3d/col/Bounds.hx

@@ -13,7 +13,7 @@ class Bounds implements Collider {
 	public var xSize(get,set) : Float;
 	public var ySize(get,set) : Float;
 	public var zSize(get,set) : Float;
-	
+
 	public inline function new() {
 		empty();
 	}
@@ -129,7 +129,37 @@ class Bounds implements Collider {
 		return ret;
 	}
 
-	public function transform3x4( m : Matrix ) {
+	public function transform3x3( m : Matrix ) {
+		var xMin = xMin, yMin = yMin, zMin = zMin, xMax = xMax, yMax = yMax, zMax = zMax;
+		empty();
+		var v = new h3d.col.Point();
+		v.set(xMin, yMin, zMin);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMin, yMin, zMax);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMin, yMax, zMin);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMin, yMax, zMax);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMax, yMin, zMin);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMax, yMin, zMax);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMax, yMax, zMin);
+		v.transform3x3(m);
+		addPoint(v);
+		v.set(xMax, yMax, zMax);
+		v.transform3x3(m);
+		addPoint(v);
+	}
+
+	public function transform( m : Matrix ) {
 		var xMin = xMin, yMin = yMin, zMin = zMin, xMax = xMax, yMax = yMax, zMax = zMax;
 		empty();
 		var v = new h3d.col.Point();
@@ -279,7 +309,7 @@ class Bounds implements Collider {
 	public inline function getMax() {
 		return new Point(xMax, yMax, zMax);
 	}
-	
+
 	inline function get_xSize() return xMax - xMin;
 	inline function get_ySize() return yMax - yMin;
 	inline function get_zSize() return zMax - zMin;

+ 41 - 1
h3d/col/Frustum.hx

@@ -25,6 +25,46 @@ class Frustum {
 		pfar.normalize();
 	}
 
+	public function transform( m : h3d.Matrix ) @:privateAccess {
+		var m2 = new h3d.Matrix();
+		m2.initInverse(m);
+		m2.transpose();
+
+		pleft.transformInverseTranspose(m2);
+		pright.transformInverseTranspose(m2);
+		ptop.transformInverseTranspose(m2);
+		pbottom.transformInverseTranspose(m2);
+		pfar.transformInverseTranspose(m2);
+		pnear.transformInverseTranspose(m2);
+
+		pleft.normalize();
+		pright.normalize();
+		ptop.normalize();
+		pbottom.normalize();
+		pnear.normalize();
+		pfar.normalize();
+	}
+
+	public function transform3x3( m : h3d.Matrix ) @:privateAccess {
+		var m2 = new h3d.Matrix();
+		m2.initInverse3x3(m);
+		m2.transpose();
+
+		pleft.transformInverseTranspose(m2);
+		pright.transformInverseTranspose(m2);
+		ptop.transformInverseTranspose(m2);
+		pbottom.transformInverseTranspose(m2);
+		pfar.transformInverseTranspose(m2);
+		pnear.transformInverseTranspose(m2);
+
+		pleft.normalize();
+		pright.normalize();
+		ptop.normalize();
+		pbottom.normalize();
+		pnear.normalize();
+		pfar.normalize();
+	}
+
 	public function hasSphere( s : Sphere ) {
 		var p = s.getCenter();
 		if( pleft.distance(p) < -s.r ) return false;
@@ -53,5 +93,5 @@ class Frustum {
 			return false;
 		return true;
 	}
-	
+
 }

+ 24 - 1
h3d/col/Plane.hx

@@ -10,7 +10,7 @@ class Plane {
 	var nz : Float;
 	var d : Float;
 
-	inline function new(nx, ny, nz, d) {
+	public inline function new(nx, ny, nz, d) {
 		this.nx = nx;
 		this.ny = ny;
 		this.nz = nz;
@@ -28,6 +28,29 @@ class Plane {
 		return d;
 	}
 
+	public function transform( m : h3d.Matrix ) {
+		var m2 = new h3d.Matrix();
+		m2.initInverse(m);
+		m2.transpose();
+		transformInverseTranspose(m2);
+	}
+
+	public function transform3x3( m : h3d.Matrix ) {
+		var m2 = new h3d.Matrix();
+		m2.initInverse3x3(m);
+		m2.transpose();
+		transformInverseTranspose(m2);
+	}
+
+	inline function transformInverseTranspose(m:h3d.Matrix) {
+		var v = new h3d.Vector(nx, ny, nz, -d);
+		v.transform(m);
+		nx = v.x;
+		ny = v.y;
+		nz = v.z;
+		d = -v.w;
+	}
+
 	/**
 		Normalize the plan, so we can use distance().
 	**/

+ 1 - 1
h3d/parts/GpuParticles.hx

@@ -475,7 +475,7 @@ class GpuParticles extends h3d.scene.MultiMaterial {
 				switch( g.emitMode ) {
 				case ParentBounds:
 					ebounds = parent.getBounds();
-					ebounds.transform3x4(getInvPos());
+					ebounds.transform(getInvPos());
 				case VolumeBounds, CameraBounds:
 					ebounds = volumeBounds;
 					if( ebounds == null ) ebounds = volumeBounds = h3d.col.Bounds.fromValues( -1, -1, -1, 2, 2, 2 );

+ 1 - 1
h3d/scene/CustomObject.hx

@@ -14,7 +14,7 @@ class CustomObject extends Object {
 	override function getBounds( ?b : h3d.col.Bounds, rec = false ) {
 		b = super.getBounds(b, rec);
 		var tmp = primitive.getBounds().clone();
-		tmp.transform3x4(absPos);
+		tmp.transform(absPos);
 		b.add(tmp);
 		return b;
 	}

+ 1 - 12
h3d/scene/Mesh.hx

@@ -17,7 +17,7 @@ class Mesh extends Object {
 		if( primitive == null )
 			return b;
 		var tmp = primitive.getBounds().clone();
-		tmp.transform3x4(absPos);
+		tmp.transform(absPos);
 		b.add(tmp);
 		return b;
 	}
@@ -30,17 +30,6 @@ class Mesh extends Object {
 		return m;
 	}
 
-	override function hardwarePickEmit(r:h3d.col.Ray, ctx:RenderContext) {
-		if( visible && !culled && primitive != null ) {
-			var save = r.clone();
-			r.transform(getInvPos());
-			if( primitive.getBounds().rayIntersection(r) != null )
-				ctx.emitPass(material.mainPass, this);
-			r.load(save);
-		}
-		super.hardwarePickEmit(r, ctx);
-	}
-
 	override function draw( ctx : RenderContext ) {
 		primitive.render(ctx.engine);
 	}

+ 6 - 2
h3d/scene/Object.hx

@@ -299,11 +299,15 @@ class Object {
 		}
 	}
 
-	function hardwarePickEmit( r : h3d.col.Ray, ctx : RenderContext ) {
+	public function iterVisibleMeshes( callb : Mesh -> Void ) {
 		if( !visible || (culled && inheritCulled) )
 			return;
+		if( !culled ) {
+			var m = Std.instance(this, Mesh);
+			if( m != null ) callb(m);
+		}
 		for( o in childs )
-			o.hardwarePickEmit(r, ctx);
+			o.iterVisibleMeshes(callb);
 	}
 
 	function onParentChangedRec() {

+ 1 - 0
h3d/scene/RenderContext.hx

@@ -13,6 +13,7 @@ private class SharedGlobal {
 class RenderContext extends h3d.impl.RenderContext {
 
 	public var camera : h3d.Camera;
+	public var scene : Scene;
 	public var drawPass : ObjectPass;
 
 	var sharedGlobals : Array<SharedGlobal>;

+ 14 - 1
h3d/scene/Scene.hx

@@ -213,10 +213,20 @@ class Scene extends Object implements h3d.IDrawable implements hxd.SceneEvents.I
 		camera.update();
 		ctx.camera = camera;
 		ctx.engine = engine;
+		ctx.scene = this;
 		ctx.start();
 
 		var ray = camera.rayFromScreen(pixelX, pixelY);
-		hardwarePickEmit(ray, ctx);
+		var savedRay = ray.clone();
+
+		iterVisibleMeshes(function(m) {
+			if( m.primitive == null ) return;
+			ray.transform(m.getInvPos());
+			if( m.primitive.getBounds().rayIntersection(ray) != null )
+				ctx.emitPass(m.material.mainPass, m);
+			ray.load(savedRay);
+		});
+
 		ctx.lightSystem = null;
 
 		var found = null;
@@ -243,6 +253,7 @@ class Scene extends Object implements h3d.IDrawable implements hxd.SceneEvents.I
 		ctx.done();
 		ctx.camera = null;
 		ctx.engine = null;
+		ctx.scene = null;
 		return found;
 	}
 
@@ -261,6 +272,7 @@ class Scene extends Object implements h3d.IDrawable implements hxd.SceneEvents.I
 		camera.update();
 		ctx.camera = camera;
 		ctx.engine = engine;
+		ctx.scene = this;
 		ctx.start();
 
 		syncRec(ctx);
@@ -305,6 +317,7 @@ class Scene extends Object implements h3d.IDrawable implements hxd.SceneEvents.I
 		#end
 
 		ctx.done();
+		ctx.scene = null;
 		ctx.camera = null;
 		ctx.engine = null;
 	}

+ 2 - 2
h3d/scene/Skin.hx

@@ -88,9 +88,9 @@ class Skin extends MultiMaterial {
 				mtmp.multiply3x4(b0.defMat, mtmp);
 			if( b0.transPos != null )
 				mtmp.multiply3x4(b0.transPos, mtmp);
-			tmp.transform3x4(mtmp);
+			tmp.transform(mtmp);
 		} else
-			tmp.transform3x4(absPos);
+			tmp.transform(absPos);
 		b.add(tmp);
 		return b;
 	}