Compare commits
1 Commits
main
...
feat/mnemo
| Author | SHA1 | Date | |
|---|---|---|---|
| 08117ef43a |
@@ -140,6 +140,47 @@ const SpatialMemory = (() => {
|
||||
return new THREE.OctahedronGeometry(size, 0);
|
||||
}
|
||||
|
||||
// ─── TRUST-BASED VISUALS ─────────────────────────────
|
||||
// Wire crystal visual properties to fact trust score (0.0-1.0).
|
||||
// Issue #1166: Trust > 0.8 = bright glow/full opacity,
|
||||
// 0.5-0.8 = medium/80%, < 0.5 = dim/40%, < 0.3 = near-invisible pulsing red.
|
||||
function _getTrustVisuals(trust, regionColor) {
|
||||
const t = Math.max(0, Math.min(1, trust));
|
||||
if (t >= 0.8) {
|
||||
return {
|
||||
opacity: 1.0,
|
||||
emissiveIntensity: 2.0 * t,
|
||||
emissiveColor: regionColor,
|
||||
lightIntensity: 1.2,
|
||||
glowDesc: 'high'
|
||||
};
|
||||
} else if (t >= 0.5) {
|
||||
return {
|
||||
opacity: 0.8,
|
||||
emissiveIntensity: 1.2 * t,
|
||||
emissiveColor: regionColor,
|
||||
lightIntensity: 0.6,
|
||||
glowDesc: 'medium'
|
||||
};
|
||||
} else if (t >= 0.3) {
|
||||
return {
|
||||
opacity: 0.4,
|
||||
emissiveIntensity: 0.5 * t,
|
||||
emissiveColor: regionColor,
|
||||
lightIntensity: 0.2,
|
||||
glowDesc: 'dim'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
opacity: 0.15,
|
||||
emissiveIntensity: 0.3,
|
||||
emissiveColor: 0xff2200,
|
||||
lightIntensity: 0.1,
|
||||
glowDesc: 'untrusted'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ─── REGION MARKER ───────────────────────────────────
|
||||
function createRegionMarker(regionKey, region) {
|
||||
const cx = region.center[0];
|
||||
@@ -216,17 +257,20 @@ const SpatialMemory = (() => {
|
||||
const region = REGIONS[mem.category] || REGIONS.working;
|
||||
const pos = mem.position || _assignPosition(mem.category, mem.id);
|
||||
const strength = Math.max(0.05, Math.min(1, mem.strength != null ? mem.strength : 0.7));
|
||||
const trust = mem.trust != null ? Math.max(0, Math.min(1, mem.trust)) : 0.7;
|
||||
const size = 0.2 + strength * 0.3;
|
||||
|
||||
const tv = _getTrustVisuals(trust, region.color);
|
||||
|
||||
const geo = createCrystalGeometry(size);
|
||||
const mat = new THREE.MeshStandardMaterial({
|
||||
color: region.color,
|
||||
emissive: region.color,
|
||||
emissiveIntensity: 1.5 * strength,
|
||||
emissive: tv.emissiveColor,
|
||||
emissiveIntensity: tv.emissiveIntensity,
|
||||
metalness: 0.6,
|
||||
roughness: 0.15,
|
||||
transparent: true,
|
||||
opacity: 0.5 + strength * 0.4
|
||||
opacity: tv.opacity
|
||||
});
|
||||
|
||||
const crystal = new THREE.Mesh(geo, mat);
|
||||
@@ -239,10 +283,12 @@ const SpatialMemory = (() => {
|
||||
region: mem.category,
|
||||
pulse: Math.random() * Math.PI * 2,
|
||||
strength: strength,
|
||||
trust: trust,
|
||||
glowDesc: tv.glowDesc,
|
||||
createdAt: mem.timestamp || new Date().toISOString()
|
||||
};
|
||||
|
||||
const light = new THREE.PointLight(region.color, 0.8 * strength, 5);
|
||||
const light = new THREE.PointLight(tv.emissiveColor, tv.lightIntensity, 5);
|
||||
crystal.add(light);
|
||||
|
||||
_scene.add(crystal);
|
||||
@@ -337,8 +383,16 @@ const SpatialMemory = (() => {
|
||||
mesh.scale.setScalar(pulse);
|
||||
|
||||
if (mesh.material) {
|
||||
const trust = mesh.userData.trust != null ? mesh.userData.trust : 0.7;
|
||||
const base = mesh.userData.strength || 0.7;
|
||||
mesh.material.emissiveIntensity = 1.0 + Math.sin(mesh.userData.pulse * 0.7) * 0.5 * base;
|
||||
if (trust < 0.3) {
|
||||
// Low trust: pulsing red — visible warning
|
||||
const pulseAlpha = 0.15 + Math.sin(mesh.userData.pulse * 2.0) * 0.15;
|
||||
mesh.material.emissiveIntensity = 0.3 + Math.sin(mesh.userData.pulse * 2.0) * 0.3;
|
||||
mesh.material.opacity = pulseAlpha;
|
||||
} else {
|
||||
mesh.material.emissiveIntensity = 1.0 + Math.sin(mesh.userData.pulse * 0.7) * 0.5 * base;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -368,6 +422,42 @@ const SpatialMemory = (() => {
|
||||
return REGIONS;
|
||||
}
|
||||
|
||||
// ─── UPDATE VISUAL PROPERTIES ────────────────────────
|
||||
// Re-render crystal when trust/strength change (no position move).
|
||||
function updateMemoryVisual(memId, updates) {
|
||||
const obj = _memoryObjects[memId];
|
||||
if (!obj) return false;
|
||||
|
||||
const mesh = obj.mesh;
|
||||
const region = REGIONS[obj.region] || REGIONS.working;
|
||||
|
||||
if (updates.trust != null) {
|
||||
const trust = Math.max(0, Math.min(1, updates.trust));
|
||||
mesh.userData.trust = trust;
|
||||
obj.data.trust = trust;
|
||||
const tv = _getTrustVisuals(trust, region.color);
|
||||
mesh.material.emissive = new THREE.Color(tv.emissiveColor);
|
||||
mesh.material.emissiveIntensity = tv.emissiveIntensity;
|
||||
mesh.material.opacity = tv.opacity;
|
||||
mesh.userData.glowDesc = tv.glowDesc;
|
||||
if (mesh.children.length > 0 && mesh.children[0].isPointLight) {
|
||||
mesh.children[0].intensity = tv.lightIntensity;
|
||||
mesh.children[0].color = new THREE.Color(tv.emissiveColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.strength != null) {
|
||||
const strength = Math.max(0.05, Math.min(1, updates.strength));
|
||||
mesh.userData.strength = strength;
|
||||
obj.data.strength = strength;
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
saveToStorage();
|
||||
console.info('[Mnemosyne] Visual updated:', memId, 'trust:', mesh.userData.trust, 'glow:', mesh.userData.glowDesc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ─── QUERY ───────────────────────────────────────────
|
||||
function getMemoryAtPosition(position, maxDist) {
|
||||
maxDist = maxDist || 2;
|
||||
@@ -507,6 +597,7 @@ const SpatialMemory = (() => {
|
||||
source: o.data.source || 'unknown',
|
||||
timestamp: o.data.timestamp || o.mesh.userData.createdAt,
|
||||
strength: o.mesh.userData.strength || 0.7,
|
||||
trust: o.mesh.userData.trust != null ? o.mesh.userData.trust : 0.7,
|
||||
connections: o.data.connections || []
|
||||
}))
|
||||
};
|
||||
@@ -653,7 +744,7 @@ const SpatialMemory = (() => {
|
||||
}
|
||||
|
||||
return {
|
||||
init, placeMemory, removeMemory, update,
|
||||
init, placeMemory, removeMemory, update, updateMemoryVisual,
|
||||
getMemoryAtPosition, getRegionAtPosition, getMemoriesInRegion, getAllMemories,
|
||||
getCrystalMeshes, getMemoryFromMesh, highlightMemory, clearHighlight, getSelectedId,
|
||||
exportIndex, importIndex, searchNearby, REGIONS,
|
||||
|
||||
Reference in New Issue
Block a user