Kaynağa Gözat

Minor API changes to avoid allocs in Camera.getFrustum and terrain.Tile.emit

trethaller 6 yıl önce
ebeveyn
işleme
085ad275a4

+ 5 - 3
h3d/Camera.hx

@@ -41,6 +41,8 @@ class Camera {
 
 	public var follow : { pos : h3d.scene.Object, target : h3d.scene.Object };
 
+	public var frustum(default, null) = new h3d.col.Frustum();
+
 	var minv : Matrix;
 	var miview : Matrix;
 	var needInv : Bool;
@@ -173,13 +175,13 @@ class Camera {
 		}
 		makeCameraMatrix(mcam);
 		makeFrustumMatrix(mproj);
+		
 		m.multiply(mcam, mproj);
+		
 		needInv = true;
 		if( miview != null ) miview._44 = 0;
-	}
 
-	public function getFrustum() {
-		return new h3d.col.Frustum(m);
+		frustum.loadMatrix(m);
 	}
 
 	public function getFrustumCorners() : Array<h3d.Vector> {

+ 18 - 7
h3d/col/Frustum.hx

@@ -10,13 +10,24 @@ class Frustum {
 	public var pfar : Plane;
 	public var checkNearFar : Bool = true;
 
-	public function new( mvp : h3d.Matrix ) {
-		pleft = Plane.frustumLeft(mvp);
-		pright = Plane.frustumRight(mvp);
-		ptop = Plane.frustumTop(mvp);
-		pbottom = Plane.frustumBottom(mvp);
-		pnear = Plane.frustumNear(mvp);
-		pfar = Plane.frustumFar(mvp);
+	public function new( ?mvp : h3d.Matrix ) {
+		pleft = Plane.X();
+		pright = Plane.X();
+		ptop = Plane.X();
+		pbottom = Plane.X();
+		pnear = Plane.X();
+		pfar = Plane.X();
+		if(mvp != null)
+			loadMatrix(mvp);
+	}
+
+	public function loadMatrix( mvp : h3d.Matrix ) {
+		pleft.load(Plane.frustumLeft(mvp));
+		pright.load(Plane.frustumRight(mvp));
+		ptop.load(Plane.frustumTop(mvp));
+		pbottom.load(Plane.frustumBottom(mvp));
+		pnear.load(Plane.frustumNear(mvp));
+		pfar.load(Plane.frustumFar(mvp));
 		pleft.normalize();
 		pright.normalize();
 		ptop.normalize();

+ 10 - 3
h3d/col/Plane.hx

@@ -28,6 +28,13 @@ class Plane {
 		return d;
 	}
 
+	public inline function load( p : Plane ) {
+		nx = p.nx;
+		ny = p.ny;
+		nz = p.nz;
+		d = p.d;
+	}
+
 	public function transform( m : h3d.Matrix ) {
 		var m2 = new h3d.Matrix();
 		m2.initInverse(m);
@@ -100,15 +107,15 @@ class Plane {
 		return new Plane(n.x,n.y,n.z,n.dot(p));
 	}
 
-	public static inline function X(v:Float) {
+	public static inline function X(v:Float=0.0) {
 		return new Plane( 1, 0, 0, v );
 	}
 
-	public static inline function Y(v:Float) {
+	public static inline function Y(v:Float=0.0) {
 		return new Plane( 0, 1, 0, v );
 	}
 
-	public static inline function Z(v:Float) {
+	public static inline function Z(v:Float=0.0) {
 		return new Plane( 0, 0, 1, v );
 	}
 

+ 1 - 1
h3d/scene/pbr/terrain/Terrain.hx

@@ -217,7 +217,7 @@ class Terrain extends Object {
 				bounds.zMax = 10000;
 				bounds.zMin = -10000;
 			}
-			if(c.getFrustum().hasBounds(bounds))
+			if(c.frustum.hasBounds(bounds))
 				res.push(tile);
 		}
 		return res;

+ 8 - 8
h3d/scene/pbr/terrain/Tile.hx

@@ -484,15 +484,15 @@ class Tile extends h3d.scene.Mesh {
 			if( surfaceWeights[i] != null) surfaceWeights[i].dispose();
 	}
 
+	var cachedBounds : h3d.col.Bounds;
 	override function emit(ctx:RenderContext){
 		if(!isReady()) return;
-		var bounds = getBounds();
-		bounds.zMax = 10000;
-		bounds.zMin = -10000;
-		if(bounds != null){
-			if(ctx.camera.getFrustum().hasBounds(bounds))
-				super.emit(ctx);
-		}else
+		if(cachedBounds == null) {
+			cachedBounds = getBounds();
+			cachedBounds.zMax = 10000;  // TODO: Use real low/high Z values
+			cachedBounds.zMin = -10000;
+		}		
+		if(ctx.camera.frustum.hasBounds(cachedBounds))
 			super.emit(ctx);
 	}
 
@@ -517,7 +517,7 @@ class Tile extends h3d.scene.Mesh {
 
 		shader.surfaceParams = getTerrain().surfaceArray.params;
 		shader.secondSurfaceParams = getTerrain().surfaceArray.secondParams;
-		shader.tileIndex = new h3d.Vector(tileX, tileY);
+		shader.tileIndex.set(tileX, tileY); // = new h3d.Vector(tileX, tileY);
 		shader.parallaxAmount = getTerrain().parallaxAmount;
 		shader.minStep = getTerrain().parallaxMinStep;
 		shader.maxStep = getTerrain().parallaxMaxStep;