Prechádzať zdrojové kódy

Adding dimension method on colliders. Adding culling with distance to pbr renderer.

clementlandrin 1 rok pred
rodič
commit
a17113ddcc

+ 4 - 0
h3d/col/Bounds.hx

@@ -389,6 +389,10 @@ class Bounds extends Collider {
 		return new Sphere((xMin + xMax) * 0.5, (yMin + yMax) * 0.5, (zMin + zMax) * 0.5, Math.sqrt(dx * dx + dy * dy + dz * dz) * 0.5);
 	}
 
+	public inline function dimension() {
+		return Math.max(xSize, Math.max(ySize, zSize));
+	}
+
 	public static inline function fromPoints( min : Point, max : Point ) {
 		var b = new Bounds();
 		b.setMin(min);

+ 12 - 0
h3d/col/Collider.hx

@@ -10,6 +10,7 @@ abstract class Collider {
 	public abstract function contains( p : Point ) : Bool;
 	public abstract function inFrustum( f : Frustum, ?localMatrix : h3d.Matrix ) : Bool;
 	public abstract function inSphere( s : Sphere ) : Bool;
+	public abstract function dimension() : Float;
 
 	#if !macro
 	public abstract function makeDebugObj() : h3d.scene.Object;
@@ -50,6 +51,10 @@ class OptimizedCollider extends Collider {
 		return a.inSphere(s) && b.inSphere(s);
 	}
 
+	public function dimension() {
+		return Math.max(a.dimension(), b.dimension());
+	}
+
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var bobj = b.makeDebugObj();
@@ -108,6 +113,13 @@ class GroupCollider extends Collider {
 		return false;
 	}
 
+	public function dimension() {
+		var d = Math.NEGATIVE_INFINITY;
+		for ( c in colliders ) {
+			d = Math.max(d, c.dimension());
+		}
+		return d;
+	}
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var ret : h3d.scene.Object = null;

+ 5 - 0
h3d/col/ObjectCollider.hx

@@ -64,6 +64,11 @@ class ObjectCollider extends Collider {
 		return res;
 	}
 
+	inline public function dimension() {
+		var scale = obj.getAbsPos().getScale();
+		return collider.dimension() * Math.max(Math.max(scale.x, scale.y), scale.z);
+	}
+
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var ret = collider.makeDebugObj();

+ 8 - 0
h3d/col/Polygon.hx

@@ -156,6 +156,10 @@ class TriPlane extends Collider {
 	}
 	#end
 
+	public function dimension() {
+		throw "Not implemented";
+		return 0.0;
+	}
 }
 
 
@@ -265,6 +269,10 @@ class Polygon extends Collider {
 		return false;
 	}
 
+	inline public function dimension() {
+		return getBounds().dimension();
+	}
+
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var points : Array<Point> = [];

+ 4 - 0
h3d/col/PolygonBuffer.hx

@@ -84,6 +84,10 @@ class PolygonBuffer extends Collider {
 		return false;
 	}
 
+	public function dimension() {
+		return getBounds().dimension();
+	}
+
 	// Möller–Trumbore intersection
 	public function rayIntersection( r : Ray, bestMatch : Bool ) : Float {
 		var i = startIndex;

+ 4 - 0
h3d/col/SkinCollider.hx

@@ -54,6 +54,10 @@ class SkinCollider extends Collider {
 		return transform.rayIntersection(r, bestMatch);
 	}
 
+	public function dimension() {
+		return currentBounds.dimension();
+	}
+
 	function checkBounds() {
 		if( !obj.jointsUpdated && lastBoundsFrame == obj.lastFrame ) return;
 		lastBoundsFrame = obj.lastFrame;

+ 4 - 0
h3d/col/Sphere.hx

@@ -97,6 +97,10 @@ class Sphere extends Collider {
 		return "Sphere{" + getCenter()+","+ hxd.Math.fmt(r) + "}";
 	}
 
+	public inline function dimension() {
+		return r;
+	}
+
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var prim = new h3d.prim.Sphere(r, 20, 15);

+ 5 - 0
h3d/col/TransformCollider.hx

@@ -78,6 +78,11 @@ class TransformCollider extends Collider {
 		return res;
 	}
 
+	public function dimension() {
+		throw "Not implemented";
+		return 0.0;
+	}
+
 	#if !macro
 	public function makeDebugObj() : h3d.scene.Object {
 		var obj = collider.makeDebugObj();

+ 29 - 2
h3d/scene/pbr/Renderer.hx

@@ -76,6 +76,7 @@ class Renderer extends h3d.scene.Renderer {
 	var currentStep : h3d.impl.RendererFX.Step;
 	var performance = new h3d.pass.ScreenFx(new h3d.shader.pbr.PerformanceViewer());
 	var indirectEnv = true;
+	var cullingDistanceFactor : Float = 0.0;
 
 	var textures = {
 		albedo : (null:h3d.mat.Texture),
@@ -209,15 +210,41 @@ class Renderer extends h3d.scene.Renderer {
 		});
 	}
 
+	inline function cullPassesWithDistance( passes : h3d.pass.PassList, f : h3d.col.Collider -> Bool ) {
+		var prevCollider = null;
+		var prevResult = true;
+		passes.filter(function(p) {
+			var col = p.obj.cullingCollider;
+			if( col == null )
+				return true;
+			if( col != prevCollider ) {
+				prevCollider = col;
+				prevResult = f(col);
+				if ( prevResult ) {
+					var dim = col.dimension() * cullingDistanceFactor;
+					dim = dim * dim;
+					prevResult = dim > ctx.camera.pos.distanceSq(p.obj.getAbsPos().getPosition());
+				}
+			}
+			return prevResult;
+		});
+	}
+
 	override function draw( name : String ) {
 		var passes = get(name);
-		cullPasses(passes, function(col) return col.inFrustum(ctx.camera.frustum));
+		if ( cullingDistanceFactor > 0.0 )
+			cullPassesWithDistance(passes, function(col) return col.inFrustum(ctx.camera.frustum));
+		else
+			cullPasses(passes, function(col) return col.inFrustum(ctx.camera.frustum));
 		defaultPass.draw(passes);
 		passes.reset();
 	}
 
 	function renderPass(p:h3d.pass.Output, passes, ?sort) {
-		cullPasses(passes, function(col) return col.inFrustum(ctx.camera.frustum));
+		if ( cullingDistanceFactor > 0.0 )
+			cullPassesWithDistance(passes, function(col) return col.inFrustum(ctx.camera.frustum));
+		else 
+			cullPasses(passes, function(col) return col.inFrustum(ctx.camera.frustum));
 		p.draw(passes, sort);
 		passes.reset();
 	}