p
This commit is contained in:
parent
d14550dad6
commit
63e10af865
86 changed files with 5400 additions and 1209 deletions
|
|
@ -16,6 +16,80 @@
|
|||
return Math.max(1, Number(global.TarinaiPerf?.performanceProfile?.().creatureBackgroundBudget || 36));
|
||||
}
|
||||
|
||||
function profileNumber(name, fallback) {
|
||||
const value = Number(global.TarinaiPerf?.performanceProfile?.()[name]);
|
||||
return Number.isFinite(value) ? value : fallback;
|
||||
}
|
||||
|
||||
function resetMechanicalCrowdPressure(worldRef) {
|
||||
const pressure = worldRef._mechanicalCrowdPressure || (worldRef._mechanicalCrowdPressure = { ids: new Set(), sources: [], active: false, count: 0, mechanical: 0, frame: 0 });
|
||||
pressure.ids.clear();
|
||||
pressure.sources.length = 0;
|
||||
pressure.active = false;
|
||||
pressure.count = 0;
|
||||
pressure.mechanical = 0;
|
||||
pressure.detailedContacts = 0;
|
||||
pressure.degradedContacts = 0;
|
||||
pressure.skippedContacts = 0;
|
||||
pressure.contactBudget = 0;
|
||||
pressure.frame = (pressure.frame || 0) + 1;
|
||||
pressure.profile = global.TarinaiPerf?.simulationOptimizationTier?.() || "balanced";
|
||||
return pressure;
|
||||
}
|
||||
|
||||
function hasMechanicalPressureSources(worldRef) {
|
||||
const counts = worldRef?.itemCounts || {};
|
||||
return Boolean((counts.rotator || 0) + (counts.reciprocator || 0) + (counts.poison_block || 0));
|
||||
}
|
||||
|
||||
function mechanicalItemActive(item, worldRef) {
|
||||
if (!item || item.dead) return false;
|
||||
const pb = global.TarinaiPhysicsBodySystem;
|
||||
const body = pb?.ensureBody?.(item, worldRef, { syncFromLegacy: false }) || item.physicsBody || null;
|
||||
const velocity = body?.velocity || {};
|
||||
const motor = body?.motor || {};
|
||||
const mech = global.TarinaiMechanicalSystem;
|
||||
if (item.type === "rotator") return Number(mech?.motionLevel?.(item) || 0) > 0.55;
|
||||
if (item.type === "reciprocator") {
|
||||
const drive = (motor.powered !== false ? Math.max(0, Number(motor.speed || item.railMotorSpeed || 0) || 0) : 0) + Math.abs(Number(velocity.linear || item.slideSpeed || 0) || 0);
|
||||
return drive > 0.08;
|
||||
}
|
||||
if (item.type === "poison_block") return Boolean(global.TarinaiMechanicalSystem?.passiveItemAwake?.(item));
|
||||
return false;
|
||||
}
|
||||
|
||||
function prepareMechanicalCrowdPressure(worldRef, visibleRect) {
|
||||
const pressure = resetMechanicalCrowdPressure(worldRef);
|
||||
if (!hasMechanicalPressureSources(worldRef)) return pressure;
|
||||
pressure.contactBudget = Math.max(1, profileNumber("pressureObstacleContactBudget", 10));
|
||||
if (!worldRef?.itemsOfType || !worldRef?.nearbyTarinai) return pressure;
|
||||
const mech = global.TarinaiMechanicalSystem;
|
||||
if (!mech?.reach) return pressure;
|
||||
const types = ["rotator", "reciprocator", "poison_block"];
|
||||
let checked = 0;
|
||||
for (const type of types) {
|
||||
for (const item of worldRef.itemsOfType(type) || []) {
|
||||
if (!item || item.dead || !mechanicalItemActive(item, worldRef)) continue;
|
||||
checked += 1;
|
||||
pressure.mechanical += 1;
|
||||
pressure.sources.push(item);
|
||||
const radius = Math.max(120, (mech.reach(item) || item.r || 80) + 140);
|
||||
const candidates = worldRef.nearbyTarinai(item.x || 0, item.y || 0, radius, true) || [];
|
||||
for (const t of candidates) {
|
||||
if (!t || t.dead || worldRef.isTarinaiHiddenInNestBox?.(t)) continue;
|
||||
if (visibleRect && !global.TarinaiGeometry?.pointInRect?.(t.x || 0, t.y || 0, visibleRect)) continue;
|
||||
pressure.ids.add(t.id || t.familyKey || t);
|
||||
}
|
||||
if (checked >= 8) break;
|
||||
}
|
||||
if (checked >= 8) break;
|
||||
}
|
||||
pressure.count = pressure.ids.size;
|
||||
pressure.active = pressure.count >= 10;
|
||||
pressure.intensity = Math.min(1, pressure.count / 44);
|
||||
return pressure;
|
||||
}
|
||||
|
||||
function consumesBackgroundBudget(cadence) {
|
||||
if (!cadence || cadence.urgent || cadence.visible) return false;
|
||||
return true;
|
||||
|
|
@ -27,6 +101,10 @@
|
|||
const visibleRect = h.updateVisibleWorldRect(worldRef, 160);
|
||||
const nearVisibleRect = h.updateVisibleWorldRect(worldRef, 520);
|
||||
const now = worldRef.time || 0;
|
||||
const pressure = prepareMechanicalCrowdPressure(worldRef, visibleRect);
|
||||
const pressureActive = Boolean(pressure?.active);
|
||||
const visibleFullBudget = pressureActive ? Math.max(1, profileNumber("pressureCreatureFullBudget", 24)) : 1000000000;
|
||||
const visibleMotionBudget = pressureActive ? Math.max(1, profileNumber("pressureCreatureMotionBudget", 36)) : 1000000000;
|
||||
const stats = {
|
||||
total: 0,
|
||||
full: 0,
|
||||
|
|
@ -47,6 +125,18 @@
|
|||
fullBudget: backgroundFullBudgetFor(worldRef),
|
||||
fullBudgetUsed: 0,
|
||||
fullBudgetSkips: 0,
|
||||
visibleFullBudget,
|
||||
visibleFullUsed: 0,
|
||||
visibleFullSkips: 0,
|
||||
visibleMotionBudget,
|
||||
visibleMotionUsed: 0,
|
||||
visibleMotionSkips: 0,
|
||||
mechanicalPressure: pressure?.count || 0,
|
||||
mechanicalPressureActive: pressureActive,
|
||||
mechanicalContactBudget: pressure?.contactBudget || 0,
|
||||
mechanicalDetailedContacts: pressure?.detailedContacts || 0,
|
||||
mechanicalDegradedContacts: pressure?.degradedContacts || 0,
|
||||
mechanicalSkippedContacts: pressure?.skippedContacts || 0,
|
||||
offscreenSkipped: 0,
|
||||
};
|
||||
const prevSpatialDeferMode = worldRef.deferSpatialRebuildMode || "";
|
||||
|
|
@ -91,6 +181,14 @@
|
|||
t._nextLowFreqUpdateAt = now + interval * (0.65 + jitter * 0.70);
|
||||
}
|
||||
if (now >= t._nextLowFreqUpdateAt) {
|
||||
if (cadence.visible && stats.visibleFullUsed >= stats.visibleFullBudget) {
|
||||
const jitter = stableUnit(t.id || t.familyKey || Math.random(), `visible-creature-budget:${Math.floor(now * 5)}`);
|
||||
t._nextLowFreqUpdateAt = now + Math.max(dt, interval * (0.20 + jitter * 0.25));
|
||||
stats.visibleFullSkips += 1;
|
||||
stats.skipped += 1;
|
||||
inc(stats.skippedStates, behaviorId);
|
||||
continue;
|
||||
}
|
||||
if (usesBackgroundBudget && stats.fullBudgetUsed >= stats.fullBudget) {
|
||||
const jitter = stableUnit(t.id || t.familyKey || Math.random(), `creature-budget:${Math.floor(now * 4)}`);
|
||||
t._nextLowFreqUpdateAt = now + Math.max(dt, interval * (0.18 + jitter * 0.18));
|
||||
|
|
@ -105,11 +203,19 @@
|
|||
t._updateAccum = 0;
|
||||
t._nextLowFreqUpdateAt = now + interval * (0.92 + jitter * 0.22);
|
||||
stats.full += 1;
|
||||
if (cadence.visible) stats.visibleFullUsed += 1;
|
||||
if (usesBackgroundBudget) stats.fullBudgetUsed += 1;
|
||||
global.TarinaiCreatureRuntime.updateOne(t, runDt, { context });
|
||||
} else if (cadence.smoothMotion) {
|
||||
if (cadence.visible && stats.visibleMotionUsed >= stats.visibleMotionBudget) {
|
||||
stats.visibleMotionSkips += 1;
|
||||
stats.skipped += 1;
|
||||
inc(stats.skippedStates, behaviorId);
|
||||
continue;
|
||||
}
|
||||
if (global.TarinaiCreatureRuntime.updateMotionOnly(t, dt, { context })) {
|
||||
stats.smooth += 1;
|
||||
if (cadence.visible) stats.visibleMotionUsed += 1;
|
||||
inc(stats.smoothStates, behaviorId);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -120,6 +226,9 @@
|
|||
} finally {
|
||||
worldRef.deferSpatialRebuildDepth = Math.max(0, (worldRef.deferSpatialRebuildDepth || 1) - 1);
|
||||
worldRef.deferSpatialRebuildMode = prevSpatialDeferMode;
|
||||
stats.mechanicalDetailedContacts = pressure?.detailedContacts || 0;
|
||||
stats.mechanicalDegradedContacts = pressure?.degradedContacts || 0;
|
||||
stats.mechanicalSkippedContacts = pressure?.skippedContacts || 0;
|
||||
worldRef._creatureUpdateStats = stats;
|
||||
if (end) end();
|
||||
}
|
||||
|
|
@ -154,7 +263,15 @@
|
|||
if (fastTarinai?.length) {
|
||||
worldRef.workStats && (worldRef.workStats.collisionRuns = (worldRef.workStats.collisionRuns || 0) + 1);
|
||||
const endCollision = global.TarinaiPerf.begin("update.tarinai.collisions") || null;
|
||||
try { worldRef.resolveTarinaiHighSpeedCollisions(dt, { fastSources: fastTarinai, threshold: collisionSpeedThreshold }); }
|
||||
try {
|
||||
const profile = global.TarinaiPerf?.performanceProfile?.() || {};
|
||||
worldRef.resolveTarinaiHighSpeedCollisions(dt, {
|
||||
fastSources: fastTarinai,
|
||||
threshold: collisionSpeedThreshold,
|
||||
maxSources: profile.collisionSourceBudget,
|
||||
maxImpacts: profile.collisionImpactBudget,
|
||||
});
|
||||
}
|
||||
finally { if (endCollision) endCollision(); }
|
||||
} else {
|
||||
worldRef.workStats && (worldRef.workStats.collisionSkips = (worldRef.workStats.collisionSkips || 0) + 1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue