فهرست منبع

added meshpray split and auto cull them

Nicolas Cannasse 4 سال پیش
والد
کامیت
6ee7ab1531
1فایلهای تغییر یافته به همراه45 افزوده شده و 5 حذف شده
  1. 45 5
      hrt/prefab/l3d/MeshSpray.hx

+ 45 - 5
hrt/prefab/l3d/MeshSpray.hx

@@ -4,7 +4,7 @@ package hrt.prefab.l3d;
 
 class MeshSprayObject extends h3d.scene.Object {
 	public var batches : Array<h3d.scene.MeshBatch> = [];
-	public var batchesMap : Map<String,{ batch : h3d.scene.MeshBatch, pivot : h3d.Matrix }> = [];
+	public var batchesMap : Map<Int,Map<String,{ batch : h3d.scene.MeshBatch, pivot : h3d.Matrix }>> = [];
 	override function getMaterials( ?arr : Array<h3d.mat.Material>, recursive=true ) {
 		if( !recursive ) {
 			// batches materials are considered local materials
@@ -18,18 +18,42 @@ class MeshSprayObject extends h3d.scene.Object {
 
 class MeshSpray extends Object3D {
 
+	@:s var split : Int;
+
+	inline function getSplitID( c : Prefab ) {
+		var c = c.to(Object3D);
+		return (Math.floor(c.x/split) * 39119 + Math.floor(c.y/split)) % 0x7FFFFFFF;
+	}
+
 	override function createObject( ctx : Context ) {
 		var mspray = new MeshSprayObject(ctx.local3d);
 		// preallocate batches so their materials can be resolved
+		var curID = 0, curMap = mspray.batchesMap.get(0);
+		if( curMap == null ) {
+			curMap = new Map();
+			mspray.batchesMap.set(0, curMap);
+		}
 		for( c in children ) {
 			if( !c.enabled || c.type != "model" ) continue;
-			var batch = mspray.batchesMap.get(c.source);
+			if( split > 0 ) {
+				var sid = getSplitID(c);
+				if( sid != curID ) {
+					curID = sid;
+					curMap = mspray.batchesMap.get(sid);
+					if( curMap == null ) {
+						curMap = new Map();
+						mspray.batchesMap.set(sid, curMap);
+					}
+				}
+			}
+			var batch = curMap.get(c.source);
 			if( batch == null ) {
 				var obj = ctx.loadModel(c.source).toMesh();
 				var batch = new h3d.scene.MeshBatch(cast(obj.primitive,h3d.prim.MeshPrimitive), obj.material, mspray);
+				batch.cullingCollider = @:privateAccess batch.instanced.bounds;
 				var multi = Std.downcast(obj, h3d.scene.MultiMaterial);
 				if( multi != null ) batch.materials = multi.materials;
-				mspray.batchesMap.set(c.source, { batch : batch, pivot : obj.defaultTransform.isIdentity() ? null : obj.defaultTransform });
+				curMap.set(c.source, { batch : batch, pivot : obj.defaultTransform.isIdentity() ? null : obj.defaultTransform });
 				mspray.batches.push(batch);
 			}
 		}
@@ -47,10 +71,18 @@ class MeshSpray extends Object3D {
 			b.begin();
 			b.worldPosition = tmp;
 		}
+		var curID = 0, curMap = mspray.batchesMap.get(0);
 		for( c in children ) {
 			if( !c.enabled || c.type != "model" )
 				continue;
-			var inf = mspray.batchesMap.get(c.source);
+			if( split > 0 ) {
+				var sid = getSplitID(c);
+				if( sid != curID ) {
+					curMap = mspray.batchesMap.get(sid);
+					curID = sid;
+				}
+			}
+			var inf = curMap.get(c.source);
 			tmp.multiply3x4(c.to(Object3D).getTransform(), pos);
 			if( inf.pivot != null ) tmp.multiply3x4(inf.pivot, tmp);
 			inf.batch.emitInstance();
@@ -200,6 +232,7 @@ class MeshSpray extends Object3D {
 	@:s var defaultConfig: MeshSprayConfig;
 	@:s var currentPresetName : String = null;
 	@:s var currentSetName : String = null;
+	@:s var split : Int = 0;
 
 	var sceneEditor : hide.comp.SceneEditor;
 
@@ -382,7 +415,7 @@ class MeshSpray extends Object3D {
 				}));
 				sprayedModels = [];
 			}
-			
+
 
 			if (previewModels.length > 0) {
 				sceneEditor.deleteElements(previewModels, () -> { }, false);
@@ -677,6 +710,13 @@ class MeshSpray extends Object3D {
 		});
 
 		super.edit(ectx);
+
+		ectx.properties.add(new Element('
+		<div class="group" name="Extra">
+		<dl>
+			<dt>Split</dt><dd><input type="range" min="0" max="2048" field="split"/></dd>
+		</dl>
+		</div>'), this);
 	}
 
 	function updateConfig() {