瀏覽代碼

Model view: add LODs support

lviguier 1 年之前
父節點
當前提交
1748cb5d5b
共有 4 個文件被更改,包括 181 次插入3 次删除
  1. 45 0
      bin/style.css
  2. 57 0
      bin/style.less
  3. 4 0
      hide/Ide.hx
  4. 75 3
      hide/view/Model.hx

+ 45 - 0
bin/style.css

@@ -3266,3 +3266,48 @@ div.gradient-box {
   text-transform: capitalize;
   text-transform: capitalize;
   font-weight: normal;
   font-weight: normal;
 }
 }
+.lods-line {
+  display: flex;
+  overflow: hidden;
+}
+.lods-line .line {
+  height: 30px;
+  margin: 10px 2px 0px 2px;
+  background-color: #151515;
+  display: flex;
+  overflow: hidden;
+  padding: 1px;
+  width: 100%;
+}
+.lods-line .line div {
+  overflow: hidden;
+  height: 100%;
+}
+.lods-line .line div:nth-child(1n) {
+  background-color: #f3e179;
+}
+.lods-line .line div:nth-child(2n) {
+  background-color: #79f37b;
+}
+.lods-line .line div:nth-child(3n) {
+  background-color: #8979f3;
+}
+.lods-line .line div:nth-child(4n) {
+  background-color: #f379ad;
+}
+.lods-line .line p {
+  margin: 0 2px 0 2px;
+  color: black;
+}
+.lods-line .cursor {
+  position: absolute;
+}
+.lods-line .cursor .cursor-line {
+  background-color: #000000;
+  height: 32px;
+  width: 2px;
+}
+.lods-line .cursor p {
+  text-align: center;
+  margin-top: 2px;
+}

+ 57 - 0
bin/style.less

@@ -3753,4 +3753,61 @@ div.gradient-box {
 			}
 			}
 		}
 		}
 	}
 	}
+}
+
+// lod specific style in model viewer
+.lods-line {
+	display:flex;
+	overflow: hidden;
+
+	.line {
+		height: 30px;
+		margin: 10px 2px 0px 2px;
+		background-color: #151515;
+		display: flex;
+		overflow: hidden;
+		padding: 1px;
+		width: 100%;
+
+		div {
+			overflow: hidden;
+			height:100%
+		}
+
+		div:nth-child(1n) {
+			background-color: #f3e179;
+		}
+
+		div:nth-child(2n) {
+			background-color: #79f37b;
+		}
+
+		div:nth-child(3n) {
+			background-color: #8979f3;
+		}
+
+		div:nth-child(4n) {
+			background-color: #f379ad;
+		}
+
+		p {
+			margin: 0 2px 0 2px;
+			color: black;
+		}
+	}
+
+	.cursor {
+		position: absolute;
+
+		.cursor-line {
+			background-color: rgb(0, 0, 0);
+			height: 32px;
+			width: 2px;
+		}
+
+		p {
+			text-align: center;
+			margin-top: 2px;
+		}
+	}
 }
 }

+ 4 - 0
hide/Ide.hx

@@ -659,6 +659,10 @@ class Ide extends hide.tools.IdeData {
 			}
 			}
 			h3d.mat.MaterialSetup.current = render;
 			h3d.mat.MaterialSetup.current = render;
 
 
+			var lods = config.current.get("lods.screenRatio");
+			if (lods != null)
+				h3d.prim.HMDModel.loadLodConfig(lods);
+
 			initMenu();
 			initMenu();
 			initLayout();
 			initLayout();
 		});
 		});

+ 75 - 3
hide/view/Model.hx

@@ -367,6 +367,7 @@ class Model extends FileView {
 	}
 	}
 
 
 	var selectedJoint : String = null;
 	var selectedJoint : String = null;
+	var selectedMesh : h3d.scene.Mesh = null;
 	var displayJoints = null;
 	var displayJoints = null;
 	function selectObject( obj : h3d.scene.Object ) {
 	function selectObject( obj : h3d.scene.Object ) {
 		if ( Std.isOfType(obj, h3d.scene.Skin.Joint) ) {
 		if ( Std.isOfType(obj, h3d.scene.Skin.Joint) ) {
@@ -478,10 +479,12 @@ class Model extends FileView {
 		'),obj);
 		'),obj);
 
 
 		var mesh = Std.downcast(obj, h3d.scene.Mesh);
 		var mesh = Std.downcast(obj, h3d.scene.Mesh);
-		if (mesh != null) {
-			var hmd = Std.downcast(mesh.primitive, h3d.prim.HMDModel);
+		var hmd = Std.downcast(mesh.primitive, h3d.prim.HMDModel);
+		selectedMesh = mesh;
 
 
-			if (hmd != null && @:privateAccess hmd.blendshape != null) {
+		if (mesh != null && hmd != null) {
+			// Blendshapes edition
+			if (@:privateAccess hmd.blendshape != null) {
 				var blendShape = new Element('
 				var blendShape = new Element('
 				<div class="group" name="Blend Shapes">
 				<div class="group" name="Blend Shapes">
 					<dt>Index</dt><dd><input id="bs-index" type="range" min="0" max="${@:privateAccess hmd.blendshape.getBlendshapeCount() - 1}" step="1" field=""/></dd>
 					<dt>Index</dt><dd><input id="bs-index" type="range" min="0" max="${@:privateAccess hmd.blendshape.getBlendshapeCount() - 1}" step="1" field=""/></dd>
@@ -492,6 +495,58 @@ class Model extends FileView {
 					@:privateAccess hmd.blendshape.setBlendshapeAmount(blendShape.find("#bs-index").val(),blendShape.find("#bs-amount").val());
 					@:privateAccess hmd.blendshape.setBlendshapeAmount(blendShape.find("#bs-index").val(),blendShape.find("#bs-amount").val());
 				});
 				});
 			}
 			}
+
+			// LODs edition
+			if (@:privateAccess hmd.lodCount() > 0) {
+				var lodsEl = new Element('
+					<div class="group" name="LODs">
+						<dt>LOD Count</dt><dd>${hmd.lodCount()}</dd>
+						<dt>Force display LOD</dt>
+						<dd>
+							<select id="select-lods">
+								<option value="-1">None</option>
+								${[ for(idx in 0...hmd.lodCount()) '<option value="${idx}">LOD ${idx}</option>'].join("")}
+							<select>
+						</dd>
+						<div class="lods-line">
+							<div class="line"></div>
+							<div class="cursor">
+								<div class="cursor-line"></div>
+								<p class="ratio">100%</p>
+							</div>
+						</div>
+					</div>
+				');
+
+				properties.add(lodsEl, null, null);
+
+				var selectLod = lodsEl.find("select");
+				selectLod.on("change", function(){
+					hmd.forcedLod = Std.int(lodsEl.find("select").val());
+				});
+
+				function getLodPercent(idxLod: Int) {
+					var lodConfig = @:privateAccess h3d.prim.HMDModel.lodConfig;
+					var prev = idxLod == 0 ? 1 : lodConfig[idxLod - 1];
+
+					return (Math.abs(prev - lodConfig[idxLod])) * 100;
+				}
+
+				var lodsLine = lodsEl.find(".line");
+				var total = 100.;
+				for (idx in 0...hmd.lodCount()) {
+					lodsLine.append(new Element('
+					<div style="${idx != hmd.lodCount() - 1 ? 'width:${getLodPercent(idx)}%;' : 'flex:1'}">
+						<p>LOD&nbsp${idx}</p>
+						<p>${total}%</p>
+					</div>'));
+
+					total -= getLodPercent(idx);
+				}
+
+				var cursor = lodsEl.find(".cursor");
+				cursor.css({top: '${lodsLine.position().top + 11}px'});
+			}
 		}
 		}
 
 
 		var select = e.find(".follow");
 		var select = e.find(".follow");
@@ -1124,6 +1179,23 @@ class Model extends FileView {
 		}
 		}
 		if( cameraMove != null )
 		if( cameraMove != null )
 			cameraMove();
 			cameraMove();
+
+		if (selectedMesh != null) {
+
+			function round(number:Float, ?precision=2): Float
+			{
+				number *= Math.pow(10, precision);
+				return Math.round(number) / Math.pow(10, precision);
+			}
+
+			var screenRatio = @:privateAccess selectedMesh.curScreenRatio;
+			var line = sceneEditor.properties.element.find(".line");
+			var cursor = sceneEditor.properties.element.find(".cursor");
+			if (cursor.length > 0) {
+				cursor?.css({left: '${line.position().left + line.width() * hxd.Math.clamp((1 - screenRatio), 0, 1)}px'});
+				cursor?.find(".ratio").text('${round(hxd.Math.clamp(screenRatio * 100, 0, 100), 2)}%');
+			}
+		}
 	}
 	}
 
 
 	public function setRenderPropsEditionVisibility(visible : Bool) {
 	public function setRenderPropsEditionVisibility(visible : Bool) {