This commit is contained in:
2026-04-28 19:07:04 -07:00
parent a3d5fa846b
commit c9acef9798
2 changed files with 12 additions and 132 deletions

View File

@ -20,13 +20,6 @@ class MorphTarget {
public var morphDataPos: Image;
public var morphDataNor: Image;
public var morphMap: Map<String, Int> = null;
public var isDirty: Bool = true;
var previousWeights: Float32Array;
var changeThreshold: FastFloat = 0.001; // skip smaller
var pendingUpdates: Map<Int, Float> = null;
var batchUpdateEnabled: Bool = true;
var lastFlushFrame: Int = 0;
public function new(data: TMorphTarget) {
initWeights(data.morph_target_defaults);
@ -49,14 +42,6 @@ class MorphTarget {
morphMap.set(name, i);
i++;
}
previousWeights = new Float32Array(morphWeights.length);
for (i in 0...morphWeights.length) {
previousWeights.set(i, morphWeights.get(i));
}
// batch system
pendingUpdates = new Map<Int, Float>();
}
inline function initWeights(defaults: Float32Array) {
@ -69,95 +54,12 @@ class MorphTarget {
public function setMorphValue(name: String, value: Float) {
var i = morphMap.get(name);
if (i != null) {
if (batchUpdateEnabled) {
pendingUpdates.set(i, value);
} else {
setMorphValueDirect(i, value);
}
morphWeights.set(i, value);
}
}
// faster indexed access
public inline function setMorphValueDirect(index: Int, value: Float) {
var current = morphWeights.get(index);
// allow explicit zero values to reset
if (value == 0.0 && current != 0.0) {
morphWeights.set(index, value);
isDirty = true;
return;
}
var delta = value - current;
if (delta < -changeThreshold || delta > changeThreshold) {
morphWeights.set(index, value);
isDirty = true;
}
}
// flush pending batch
public function flushBatchedUpdates() {
if (pendingUpdates.keys().hasNext()) {
var anyChanged = false;
var hasZeros = false;
for (index in pendingUpdates.keys()) {
var value = pendingUpdates.get(index);
if (value == null) continue;
if (value == 0.0) hasZeros = true;
var current = morphWeights.get(index);
var delta = value - current;
if (value == 0.0 && current != 0.0) {
try{
morphWeights.set(index, cast value);
}catch(e){
trace("ERROR: " + e);
}
anyChanged = true;
}
else if (delta < -changeThreshold || delta > changeThreshold) {
morphWeights.set(index, cast value);
anyChanged = true;
}
}
pendingUpdates.clear();
if (anyChanged || hasZeros) {
isDirty = true;
}
}
}
public inline function markClean() {
isDirty = false;
for (i in 0...morphWeights.length) {
previousWeights.set(i, morphWeights.get(i));
}
}
public inline function markDirty() {
isDirty = true;
}
// toggle batch mode
public inline function setBatchMode(enabled: Bool) {
if (!enabled && batchUpdateEnabled) {
flushBatchedUpdates();
}
batchUpdateEnabled = enabled;
}
public function resetAllWeights() {
for (i in 0...morphWeights.length) {
morphWeights.set(i, 0.0);
}
pendingUpdates.clear();
isDirty = true;
morphWeights.set(index, value);
}
}

View File

@ -68,10 +68,6 @@ class Uniforms {
public static var defaultFilter = TextureFilter.LinearFilter;
#end
#if lnx_morph_target
public static var forceUploadMorphWeights: Bool = false;
#end
public static function setContextConstants(g: Graphics, context: ShaderContext, bindParams: Array<String>) {
if (context.raw.constants != null) {
for (i in 0...context.raw.constants.length) {
@ -1361,38 +1357,20 @@ class Uniforms {
#end // lnx_clusters
#if lnx_morph_target
case "_morphWeights": {
var morphTarget = cast(object, MeshObject).morphTarget;
morphTarget.flushBatchedUpdates();
if (forceUploadMorphWeights) {
fa = morphTarget.morphWeights;
}
else {
if (morphTarget.isDirty) {
fa = morphTarget.morphWeights;
}
else {
return;
}
}
fa = cast(object, MeshObject).morphTarget.morphWeights;
}
#end
}
}
if (fa == null && externalFloatsLinks != null) {
for (fn in externalFloatsLinks) {
fa = fn(object, currentMat(object), c.link);
if (fa != null) break;
}
}
if (fa == null && externalFloatsLinks != null) {
for (fn in externalFloatsLinks) {
fa = fn(object, currentMat(object), c.link);
if (fa != null) break;
}
}
if (fa == null) return;
if (fa == null) return;
g.setFloats(location, fa);
#if lnx_morph_target
if (c.link == "_morphWeights") {
cast(object, MeshObject).morphTarget.markClean();
}
#end
}
else if (c.type == "int") {
var i: Null<Int> = null;