Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
fde0787
Localization: Lao support, quoted-CSV values, dynamic font atlas
RomeXO10 Sep 25, 2026
c00b829
Module 3: deterministic epidemic model and its calibration suite
RomeXO10 Sep 25, 2026
4f3eedf
Module 3: receive simulation parameters from GAMA as CSV, mid-session
RomeXO10 Sep 25, 2026
ae4f0af
Module 3: implementation roadmap and 3D asset brief
RomeXO10 Sep 25, 2026
6428f41
Module 3: update the roadmap with build status and the GAMA parameter…
RomeXO10 Sep 25, 2026
7b19c4b
Module 3: session, turns and the handover that carries the time
RomeXO10 Sep 25, 2026
d0ce102
Module 3: keep the shipped parameter file from drifting
RomeXO10 Sep 25, 2026
d74c295
Module 3: roadmap status after the session layer
RomeXO10 Sep 25, 2026
5f6b581
Module 3: refuse a net that helps the well nearly as much as a patient
RomeXO10 Sep 25, 2026
3074b55
Module 3: reconcile the asset brief with the delivered placeholders
RomeXO10 Sep 25, 2026
de0edef
Module 3: the debrief, the map, the trace-back and section 10 scoring
RomeXO10 Sep 25, 2026
655af22
Module 3: greybox placeholder models for the §4 asset gap
RomeXO10 Sep 25, 2026
7c254d4
Module 3: bind the household and villager views to the placeholder props
RomeXO10 Sep 25, 2026
0908393
Module 3: animation brief for the villagers
RomeXO10 Sep 25, 2026
8e4bb2d
Module 3: a scene that runs, built from data rather than dressed by hand
RomeXO10 Sep 26, 2026
81cddb6
Module 3: roadmap status after the scene
RomeXO10 Sep 26, 2026
4561442
Module 3: correct the animation brief's account of what art already e…
RomeXO10 Sep 26, 2026
3704c43
Module 3: tell the animator how much of the illness the body should c…
RomeXO10 Sep 26, 2026
3c6252f
Module 3: the squad layer - Coach brief, handover screen, debrief, jo…
RomeXO10 Sep 26, 2026
339a276
Module 3: roadmap status after the squad layer
RomeXO10 Sep 26, 2026
08bf2fb
Module 3: give the improving villager its own clip, and send the refe…
RomeXO10 Sep 26, 2026
7505460
Lao font: make the dynamic atlas readable so glyphs can be added
RomeXO10 Sep 29, 2026
b9d82f8
Module 3: space plots 11 m apart so neighbouring houses stop intersec…
RomeXO10 Sep 29, 2026
d53ff5c
Module 3: debug driver frames the selected house
RomeXO10 Sep 29, 2026
f0ac5fc
Module 3: put the yard containers in the yard, not inside the house
RomeXO10 Sep 29, 2026
a6be003
Module 3: HUD and journal actually subscribe to the session's events
RomeXO10 Sep 29, 2026
c007f30
Module 3: the 'nothing urgent' brief no longer sends you to houses yo…
RomeXO10 Sep 29, 2026
6422c47
Module 3: hold the turn clock while the handover screen is up
RomeXO10 Sep 29, 2026
a86f2c9
Module 3 HUD: status bar says the session is over instead of 'Turn 19…
RomeXO10 Sep 29, 2026
e052b9d
Module 3: an unneeded referral no longer silences the patient's later…
RomeXO10 Sep 29, 2026
58d1a99
Module 3 text: consistent 'they' for villagers; handover lines name t…
RomeXO10 Sep 29, 2026
8f38a2b
Module 3: judge 'was the source under a net' on the day the mosquito fed
RomeXO10 Sep 29, 2026
99c03bf
Module 3 journal: readable score lines and same-house cases
RomeXO10 Sep 29, 2026
e7fcdbc
Module 3 tests: a net put up after the bite is not blamed for the case
RomeXO10 Sep 29, 2026
6127770
Module 3: the room shows each villager's real state from the first tu…
RomeXO10 Sep 29, 2026
49e8a1f
Debug overlay: hidden until a controller sequence reveals it
RomeXO10 Sep 29, 2026
33763b5
Module 3: mount the window screen in the window, not mid-room
RomeXO10 Sep 29, 2026
283f916
Module 3: villagers stand still, facing the visitor, sized by age
RomeXO10 Sep 29, 2026
7ede75b
Module 3: rural surroundings - sky, grass, paddies, tree line, hills
RomeXO10 Sep 29, 2026
3e4b120
Module 3: beds render, villagers lie on them, bigger fan, one yard ja…
RomeXO10 Sep 29, 2026
ee75b7e
Module 3: the Pilot plays in a headset, with controllers
RomeXO10 Sep 29, 2026
19045fd
Module 3 VR: no jump, working teleport, floor tracking
RomeXO10 Sep 29, 2026
c15ac5d
Module 3 HUD: handover and debrief text shrinks to fit its panel
RomeXO10 Sep 29, 2026
b906673
Module 3: the rolled net hangs from the bed post, and no prop draws b…
RomeXO10 Sep 29, 2026
4eba589
Module 3: palm leaves render green, not white
RomeXO10 Sep 29, 2026
59fd1ad
Module 3: final art for the nine prop placeholders
RomeXO10 Sep 29, 2026
6de5c69
Module 3: child and elder villager bodies, and one visible body per a…
RomeXO10 Sep 29, 2026
225710d
Module 3: villager skin reads warm brown under the scene's lighting
RomeXO10 Sep 29, 2026
4c27882
Module 3: paint the ground - patchy grass and a rutted dirt track
RomeXO10 Sep 29, 2026
882ea16
Module 3: worn dirt yards and a path to each house's side door
RomeXO10 Sep 29, 2026
4aaff7d
Module 3: a little surface texture on the Lao house
RomeXO10 Sep 29, 2026
befd5c0
Module 3: villagers stand in the far corner, clear of the door-to-bed…
RomeXO10 Sep 29, 2026
292a309
Module 3: villager talk colliders are body-sized, not a metre wide
RomeXO10 Sep 29, 2026
172ec30
Module 3: give the unrigged adult bodies a skeleton, so sick patients…
RomeXO10 Sep 29, 2026
90d7409
Module 3: the person panel stays open for the reply to an action that…
RomeXO10 Sep 29, 2026
2227402
Module 3 Create scene demo
sophamixay2018-eng Oct 14, 2026
2f0a4ab
Module 3 Add Terrmomiter gun model
sophamixay2018-eng Oct 14, 2026
c1e771e
Revert "Module 3 Add Terrmomiter gun model"
sophamixay2018-eng Oct 14, 2026
ff34182
Merge main into module-3-scene-update
sophamixay2018-eng Oct 14, 2026
0d706f9
Add Base System for M3
BiyuBoy Oct 14, 2026
28fb3fa
Fix Npc Bug
BiyuBoy Oct 15, 2026
a1d56b2
no message
BiyuBoy Oct 15, 2026
a88177d
Merge branch 'Module-3-Demo' into module-3-scene-update
BiyuBoy Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions Assets/1.TeamWorkspace/Module3.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/1.TeamWorkspace/Module3/Data.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/1.TeamWorkspace/Module3/Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions Assets/1.TeamWorkspace/Module3/Editor/M3DesktopCameraMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using UnityEditor;

/// <summary>
/// AEDES > Module 3 > Use Desktop Camera: play the scene with the plain camera and the keyboard
/// driver instead of the XR rig - for working on the scene without a headset. Off by default, so
/// the scene plays the way it ships.
/// </summary>
public static class M3DesktopCameraMenu
{
private const string Path = "AEDES/Module 3/Use Desktop Camera";

[MenuItem(Path)]
private static void Toggle() =>
EditorPrefs.SetBool(M3XRPlayer.DesktopCameraPref, !EditorPrefs.GetBool(M3XRPlayer.DesktopCameraPref, false));

[MenuItem(Path, true)]
private static bool Validate()
{
Menu.SetChecked(Path, EditorPrefs.GetBool(M3XRPlayer.DesktopCameraPref, false));
return true;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

119 changes: 119 additions & 0 deletions Assets/1.TeamWorkspace/Module3/Editor/Module3HouseSurfaceAssets.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System.IO;
using Unity.Mathematics;
using UnityEditor;
using UnityEngine;
using static Unity.Mathematics.math;

/// <summary>
/// Generates the assets behind the Module 3 house surface: a small seamless detail texture, and two
/// materials that are the Lao house's own palette materials switched to the "AEDES/Module 3/House Lit"
/// shader with that texture.
///
/// Why not just edit the house's materials: PF_Lao_House_One_FloorV2 and M_Gradient(_Light) are shared
/// by Modules 1 and 2, and the house's UVs only pick a colour out of a palette (each face samples one
/// flat swatch), so an ordinary detail map has nothing to grip. The shader projects the texture from
/// world space instead, and M3HouseSurface swaps these materials onto the houses Module 3 builds.
///
/// The results are committed (under Assets/Resources so a build always includes them and their shader
/// variants); this menu item exists so they can be regenerated rather than hand-edited:
/// Unity -batchmode -quit -projectPath . -executeMethod Module3HouseSurfaceAssets.Generate
/// </summary>
public static class Module3HouseSurfaceAssets
{
private const string Folder = "Assets/Resources/Module3";
private const string TexturePath = Folder + "/T_M3_HouseDetail.png";
private const string ShaderName = "AEDES/Module 3/House Lit";
private const int Size = 256;

/// <summary>The house material each replacement is a copy of, and the asset it becomes.</summary>
private static readonly (string source, string asset)[] Materials =
{
("M_Gradient_Light", Folder + "/M_M3_House_Light.mat"), // walls and roof
("M_Gradient", Folder + "/M_M3_House_Door.mat"), // door leaves
};

[MenuItem("AEDES/Module 3/Generate House Surface Assets")]
public static void Generate()
{
WriteTexture();
var texture = AssetDatabase.LoadAssetAtPath<Texture2D>(TexturePath);
var shader = Shader.Find(ShaderName);
if (shader == null) { Debug.LogError($"Shader '{ShaderName}' not found - has it imported?"); return; }

foreach (var (source, asset) in Materials)
{
var original = FindMaterial(source);
if (original == null) { Debug.LogError($"House material '{source}' not found."); continue; }

var material = AssetDatabase.LoadAssetAtPath<Material>(asset);
bool isNew = material == null;
if (isNew) material = new Material(shader);
material.CopyPropertiesFromMaterial(original);
material.shaderKeywords = original.shaderKeywords;
// The copy replaces the property sheet with the original's, which lacks the detail map;
// assigning the shader again is what adds it, and SetTexture ignores unknown properties.
material.shader = shader;
if (!material.HasProperty("_M3DetailMap")) { Debug.LogError($"{asset} has no _M3DetailMap property."); continue; }
material.SetTexture("_M3DetailMap", texture);
if (isNew) AssetDatabase.CreateAsset(material, asset);
else EditorUtility.SetDirty(material);
}
AssetDatabase.SaveAssets();
Debug.Log("Module 3: house surface assets generated in " + Folder);
}

private static Material FindMaterial(string name)
{
foreach (var guid in AssetDatabase.FindAssets(name + " t:Material"))
{
var m = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(guid));
if (m != null && m.name == name && m.shader.name == "Universal Render Pipeline/Lit") return m;
}
return null;
}

/// <summary>
/// R: grain and blotches. G: streaks that run down the v axis, which the shader turns into rain
/// streaks on walls and runs down the slope on a roof. Both are centred on 0.5, so on average
/// they leave the palette colour alone. Every octave is periodic, so the texture tiles.
/// </summary>
private static void WriteTexture()
{
var pixels = new Color32[Size * Size];
for (int y = 0; y < Size; y++)
{
for (int x = 0; x < Size; x++)
{
float2 uv = float2(x + 0.5f, y + 0.5f) / Size;
float grain = 0.55f * Periodic(uv, 64, 64, 0f) + 0.30f * Periodic(uv, 16, 16, 31f) + 0.15f * Periodic(uv, 4, 4, 77f);
float streak = 0.60f * Periodic(uv, 40, 3, 13f) + 0.40f * Periodic(uv, 17, 2, 53f);
pixels[y * Size + x] = new Color32(ToByte(grain), ToByte(streak), 128, 255);
}
}

var texture = new Texture2D(Size, Size, TextureFormat.RGBA32, false, true);
texture.SetPixels32(pixels);
Directory.CreateDirectory(Folder);
File.WriteAllBytes(TexturePath, texture.EncodeToPNG());
Object.DestroyImmediate(texture);
AssetDatabase.ImportAsset(TexturePath, ImportAssetOptions.ForceSynchronousImport);

// Data, not colour: linear, tiled, mipmapped so it fades to the average at a distance.
var importer = (TextureImporter)AssetImporter.GetAtPath(TexturePath);
importer.sRGBTexture = false;
importer.mipmapEnabled = true;
importer.wrapMode = TextureWrapMode.Repeat;
importer.filterMode = FilterMode.Trilinear;
importer.anisoLevel = 4;
importer.textureCompression = TextureImporterCompression.CompressedHQ;
importer.SaveAndReimport();
}

private static float Periodic(float2 uv, int cyclesX, int cyclesY, float offset)
{
var cycles = float2(cyclesX, cyclesY);
return noise.pnoise(uv * cycles + offset, cycles);
}

private static byte ToByte(float signed) => (byte)(saturate(0.5f + 0.5f * signed * 1.3f) * 255f + 0.5f);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions Assets/1.TeamWorkspace/Module3/Editor/Module3ParameterTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.IO;
using Aedes.Module3.Sim;
using UnityEditor;
using UnityEngine;

/// <summary>
/// Regenerates the parameter CSV that ships in Resources and that the GAMA modellers work from.
///
/// This exists because the file drifted once already: a default changed in Module3Config, the CSV
/// kept the old value, and the file the build loads at startup no longer passed its own
/// validation. Regenerating by hand is exactly the step that gets forgotten, so it is a menu item
/// and a test rather than a note in a document.
/// </summary>
public static class Module3ParameterTemplate
{
public const string Path = "Assets/Resources/Module3/Module3Parameters.csv";

[MenuItem("Module 3/Regenerate parameter template")]
public static void Regenerate()
{
string csv = ParameterCsv.WriteTemplate(new ParameterSet());

var check = ParameterCsv.Parse(csv, "regenerated");
if (!check.IsValid)
{
// The defaults in Module3Config no longer satisfy the rules in ParameterCsv. Writing
// the file anyway would just move the failure to startup.
Debug.LogError("Module 3: the built-in defaults do not pass validation, so the template was "
+ "NOT written:\n " + string.Join("\n ", check.Errors));
return;
}

Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Path));
File.WriteAllText(Path, csv);
AssetDatabase.ImportAsset(Path);
Debug.Log($"Module 3: parameter template regenerated at {Path} "
+ $"({ParameterCsv.Descriptors.Count} keys). Hand this to the GAMA modellers.");
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading