Refactor Assets/Scripts: trim restating comments, minor structure cleanups

Sweep over 48 files (Editor/ excluded): remove comments that restate the
code, condense class summaries, fix three stale doc statements
(HsvColorPicker alpha bar, PaintHud layoutPrefab, MasterVolume
FallbackDefault). Inline two single-use wrappers (IsPointerOverUi,
BuildModes), drop an unused using, replace a magic literal with the
existing ParallaxBase constant, and convert ~10 UnityEngine.Object null
checks to the implicit-bool convention. No serialized fields, signatures,
RPC/NetworkVariable names, defaults, or #if blocks touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5 committed 2026-07-08 08:29:18 +02:00
1 parent eeee5fc2f0
commit 6c03e5d3f6
48 files changed
+289 -481

No files matched your search

@@ -7,26 +7,21 @@ using UnityEditor.SceneManagement;
#endif
/// <summary>
/// Editor tool that decomposes an environment mesh (typically an open-shell / non-watertight
/// furniture mesh) into a small set of CONVEX MeshColliders via surface clustering, so
/// <see cref="ConcealmentMeter"/> can treat the furniture as "embeddable" through its
/// convex-collider ClosestPoint path WITHOUT a single convex hull filling the open compartments.
/// Editor tool that decomposes an environment mesh (typically open-shell furniture) into a small set
/// of CONVEX MeshColliders via surface clustering, so <see cref="ConcealmentMeter"/> can treat the
/// furniture as "embeddable" through its convex-collider ClosestPoint path WITHOUT a single convex
/// hull filling the open compartments.
///
/// Approach (no voxels, no native plugin — "approximate convex decomposition" on the surface):
/// 1. Weld coincident vertices so connectivity is detected across split-normal/UV seams.
/// 2. Grow connected triangle regions into SLABS: a region keeps absorbing edge-adjacent
/// triangles while it stays thinner than <see cref="maxSlabThickness"/> along its flattest
/// axis (PCA minor axis). This spans both faces of one board (they are within a board's
/// thickness) but refuses to jump the gap to the next board (that would thicken the region).
/// 3. Convex-hull each slab into its own convex collider. Boards become thin convex slabs;
/// the empty space between boards is covered by no collider, so it stays hollow.
/// Approach (approximate convex decomposition on the surface — no voxels, no native plugin): weld
/// coincident vertices so connectivity survives split-normal/UV seams, grow edge-connected triangle
/// regions into SLABS kept thinner than <see cref="maxSlabThickness"/> along their PCA minor axis
/// (spans both faces of one board, refuses to jump the gap to the next), then convex-hull each slab.
/// The empty space between boards is covered by no collider, so it stays hollow.
///
/// The colliders are real child GameObjects referencing SAVED hull-mesh assets, so they survive
/// domain reload / play-mode / scene save (unlike an in-memory-only bake).
///
/// Runtime-inert: the component exists only so <see cref="ConcealmentMeter"/> can detect it in a
/// collider's parent and skip the furniture's own concave MeshCollider (exactly like a baked
/// <c>ConcealmentVolume</c> does) — the generated convex slabs are the authoritative embedding shape.
/// domain reload / play mode / scene save. Runtime-inert: the component exists only so
/// <see cref="ConcealmentMeter"/> can detect it in a collider's parent and skip the furniture's own
/// concave MeshCollider — the generated convex slabs are the authoritative embedding shape.
/// </summary>
[DisallowMultipleComponent]
public class ConcealmentColliderBaker : MonoBehaviour
@@ -240,7 +235,7 @@ public class ConcealmentColliderBaker : MonoBehaviour
AssetDatabase.SaveAssets();
EditorUtility.SetDirty(this);
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
EditorSceneManager.MarkSceneDirty(gameObject.scene);
Debug.Log($"[ConcealmentColliderBaker] '{name}': baked {made} convex collider(s)" +
(dropped > 0 ? $" (+{dropped} smaller slab(s) dropped by Max Colliders={maxColliders})" : "") +
@@ -262,7 +257,7 @@ public class ConcealmentColliderBaker : MonoBehaviour
EditorUtility.SetDirty(this);
if (gameObject.scene.IsValid())
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
EditorSceneManager.MarkSceneDirty(gameObject.scene);
}
private static void EnsureFolder()
@@ -2,27 +2,19 @@ using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Standalone volumetric concealment meter for the painted character.
///
/// Each evaluation bakes the character's current (deformed) skinned mesh, voxelizes its
/// SOLID volume, and reports what fraction of that volume sits INSIDE environment colliders
/// (= embedded / hidden) versus exposed. <see cref="EmbeddedPercent"/> is the headline value,
/// Standalone volumetric concealment meter for the painted character. Each evaluation bakes the
/// current (deformed) skinned mesh, voxelizes its SOLID volume, and reports the fraction embedded
/// inside environment colliders: <see cref="EmbeddedPercent"/> is the headline value,
/// <see cref="visiblePercent"/> its complement.
///
/// Pipeline:
/// 1. <see cref="SkinnedMeshRenderer.BakeMesh(Mesh)"/> -> mesh in the renderer's LOCAL space, then the
/// player's world scale is divided back out (BakeMesh bakes that scale IN; see PlayerScaler) so the
/// convention world = transform.localToWorldMatrix holds at ANY size — the same fixup SkinnedColliderBaker
/// applies, and the unit-scale mesh MeshPainter borrows from it.
/// 2. Column ray-stabbing in local space: each (x,z) grid column collects the Y where the mesh
/// surface crosses it; parity (odd # of crossings below a voxel center) marks interior voxels.
/// This is the same XZ triangle rasterization MeshPainter.GetIslandMask uses for UV islands.
/// 3. Each interior voxel center -> world; tested against broadphase-filtered environment
/// colliders: convex primitives / convex MeshCollider via ClosestPoint, Terrain via
/// SampleHeight, optional concave MeshCollider via raycast parity.
/// Pipeline: BakeMesh with the player's world scale divided back out (see Evaluate), then column
/// ray-stabbing in local space — odd # of surface crossings below a voxel center marks it interior
/// (same XZ triangle rasterization MeshPainter.GetIslandMask uses) — then each interior voxel center
/// is tested in world space against broadphase-filtered environment colliders: convex via
/// ClosestPoint, Terrain via SampleHeight, optional concave MeshCollider via raycast parity.
///
/// Surface-watertightness caveat: parity assumes a closed mesh. After the Blender merge-by-distance
/// the paintman rig is effectively watertight; small leaks only perturb the percentage slightly.
/// Watertightness caveat: parity assumes a closed mesh. After the Blender merge-by-distance the
/// paintman rig is effectively watertight; small leaks only perturb the percentage slightly.
/// </summary>
[DisallowMultipleComponent]
public class ConcealmentMeter : MonoBehaviour
@@ -134,12 +126,11 @@ public class ConcealmentMeter : MonoBehaviour
targetRenderer.BakeMesh(_baked);
// BakeMesh freezes the bone deformation — which already carries the player's world scale (PlayerScaler)
// — into the mesh. Everything below treats the bake as unit-scale LOCAL geometry and raises it to world
// via targetRenderer.localToWorldMatrix, which re-applies that same scale. Divide it back out first,
// else a scaled player is measured at scale² (voxel world positions, broadphase box AND gizmos), which
// also corrupts EmbeddedPercent. No-op at scale 1; the uniform divide is rotation-independent, which the
// player's uniform scale guarantees. Mirrors SkinnedColliderBaker's identical fixup.
// BakeMesh freezes the bone deformation — which already carries the player's world scale
// (PlayerScaler) — into the mesh, and everything below re-applies that scale by raising the
// bake to world via localToWorldMatrix, so a scaled player would be measured at scale²,
// corrupting EmbeddedPercent. Divide it back out first. No-op at scale 1; the player's
// uniform scale makes the divide rotation-independent. Mirrors SkinnedColliderBaker's fixup.
GeometryUtil.RescaleToUnitScale(_baked, targetRenderer.transform.lossyScale, _vbuf);
// mesh.vertices/.triangles return fresh arrays per call - at 10 evals/s that is steady GC
@@ -361,7 +352,7 @@ public class ConcealmentMeter : MonoBehaviour
TerrainData td = terr.terrainData;
float lx = p.x - tp.x, lz = p.z - tp.z;
if (lx < 0f || lz < 0f || lx > td.size.x || lz > td.size.z) continue;
if (p.y <= tp.y + terr.SampleHeight(p)) return true; // below the surface
if (p.y <= tp.y + terr.SampleHeight(p)) return true;
}
}
@@ -4,19 +4,16 @@ using UnityEngine;
/// <summary>
/// Editor-baked solid/enclosed voxel volume for a single (typically non-convex, non-watertight)
/// environment mesh. Runtime lookup is an O(1) grid test, so <see cref="ConcealmentMeter"/> can
/// treat furniture as "embeddable" without per-voxel raycast parity (which is unreliable on the
/// open-shell furniture meshes of asset kits).
/// treat furniture as "embeddable" without per-voxel raycast parity (unreliable on the open-shell
/// furniture meshes of asset kits).
///
/// Bake (editor only): voxelizes the source mesh in LOCAL space and marks a voxel as INSIDE when
/// either classifier fires:
/// * Generalized Winding Number &gt; 0.5 -> robustly captures SOLID material even for open shells.
/// * Exterior flood-fill cannot reach it -> captures fully ENCLOSED air cavities.
/// The union is conservative in the safe direction: an unreachable solid OR an enclosed pocket both
/// count as concealment; open regions (seat surface, under a thin table) correctly read as exposed.
/// The bake marks a voxel INSIDE when either classifier fires: generalized winding number &gt; 0.5
/// (captures SOLID material, robust for open shells) OR unreachable by exterior flood-fill
/// (captures fully ENCLOSED air cavities). The union errs in the safe direction — solid or enclosed
/// both count as concealment; open regions (seat surface, under a thin table) read as exposed.
///
/// Query is done via <see cref="ContainsWorld"/>; bake and query share the SAME mesh-local space
/// (verts at bake time, transform.InverseTransformPoint at query time), so position/rotation/scale
/// are handled uniformly.
/// Bake and query (<see cref="ContainsWorld"/>) share the SAME mesh-local space, so
/// position/rotation/scale are handled uniformly.
/// </summary>
[DisallowMultipleComponent]
public class ConcealmentVolume : MonoBehaviour