Skip to content

Commit eb6fa12

Browse files
committed
bugfix
1 parent 511cd38 commit eb6fa12

28 files changed

Lines changed: 1215 additions & 196 deletions

src/main/java/com/hfstudio/guidenh/guide/internal/MutableGuide.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ && isForDefaultLanguage(change)) {
400400
} else {
401401
developmentPages.remove(pageId);
402402
}
403+
removeCompiledPage(pageId);
403404

404405
changes.set(i, new GuidePageChange(change.language(), pageId, initialPages.get(pageId), newPage));
405406
}
@@ -501,9 +502,7 @@ public void applyEditorPage(ParsedGuidePage parsedPage) {
501502
}
502503
ResourceLocation pageId = parsedPage.getId();
503504
developmentPages.put(pageId, parsedPage);
504-
synchronized (compiledPages) {
505-
compiledPages.remove(parsedPage);
506-
}
505+
removeCompiledPage(pageId);
507506
if (parsedPage.hasParseFailure()) {
508507
recordParseFailure(parsedPage);
509508
} else {
@@ -512,6 +511,13 @@ public void applyEditorPage(ParsedGuidePage parsedPage) {
512511
}
513512
}
514513

514+
private void removeCompiledPage(ResourceLocation pageId) {
515+
synchronized (compiledPages) {
516+
compiledPages.keySet()
517+
.removeIf(page -> page != null && pageId.equals(page.getId()));
518+
}
519+
}
520+
515521
public void rebuildEditorNavigationState() {
516522
rebuildIndices();
517523
navigationTree = buildNavigation();

src/main/java/com/hfstudio/guidenh/guide/internal/editor/md/SceneEditorMarkdownCodec.java

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,20 @@ public class SceneEditorMarkdownCodec {
6666
.unmodifiableSet(new HashSet<>(Arrays.asList("pos", "color", "thickness", "alwaysOnTop", "visible")));
6767
public static final Set<String> BOX_ATTRIBUTES = Collections
6868
.unmodifiableSet(new HashSet<>(Arrays.asList("min", "max", "color", "thickness", "alwaysOnTop", "visible")));
69-
public static final Set<String> LINE_ATTRIBUTES = Collections
70-
.unmodifiableSet(new HashSet<>(Arrays.asList("from", "to", "color", "thickness", "alwaysOnTop", "visible")));
69+
public static final Set<String> LINE_ATTRIBUTES = Collections.unmodifiableSet(
70+
new HashSet<>(
71+
Arrays.asList(
72+
"from",
73+
"to",
74+
"points",
75+
"arrow",
76+
"color",
77+
"thickness",
78+
"alwaysOnTop",
79+
"visible",
80+
"showPoints",
81+
"pointColor",
82+
"pointSize")));
7183
public static final Set<String> DIAMOND_ATTRIBUTES = Collections
7284
.unmodifiableSet(new HashSet<>(Arrays.asList("pos", "color", "alwaysOnTop", "visible")));
7385
public static final Set<String> TEXT_ATTRIBUTES = Collections.unmodifiableSet(
@@ -241,8 +253,14 @@ private SceneEditorElementModel parseElement(MdxJsxElementFields element, String
241253
if ("LineAnnotation".equals(tagName)) {
242254
ensureAllowedAttributes(element, LINE_ATTRIBUTES, tagName);
243255
SceneEditorElementModel model = new SceneEditorElementModel(SceneEditorElementType.LINE);
244-
applyPrimary(model, parseVectorAttribute(element, "from", new float[] { 0f, 0f, 0f }));
245-
applySecondary(model, parseVectorAttribute(element, "to", new float[] { 0f, 0f, 0f }));
256+
float[][] points = parseLinePointsAttribute(element);
257+
if (points != null) {
258+
applyPrimary(model, points[0]);
259+
applySecondary(model, points[points.length - 1]);
260+
} else {
261+
applyPrimary(model, parseVectorAttribute(element, "from", new float[] { 0f, 0f, 0f }));
262+
applySecondary(model, parseVectorAttribute(element, "to", new float[] { 0f, 0f, 0f }));
263+
}
246264
model.setColorLiteral(parseColorAttribute(element, model.getColorLiteral()));
247265
model.setThickness(parseFloatAttribute(element, "thickness", model.getThickness()));
248266
model.setAlwaysOnTop(parseBooleanAttribute(element, "alwaysOnTop", model.isAlwaysOnTop()));
@@ -908,6 +926,31 @@ private float[] parseVectorAttribute(MdxJsxElementFields element, String name, f
908926
return pieces;
909927
}
910928

929+
private float[][] parseLinePointsAttribute(MdxJsxElementFields element) {
930+
String rawValue = getOptionalAttributeValue(element, "points");
931+
if (rawValue == null || rawValue.trim()
932+
.isEmpty()) {
933+
return null;
934+
}
935+
String[] tokens = rawValue.split(";");
936+
List<float[]> points = new ArrayList<>();
937+
for (String token : tokens) {
938+
String trimmed = token.trim();
939+
if (trimmed.isEmpty()) {
940+
continue;
941+
}
942+
float[] point = MdxAttrs.parseVector3Parts(trimmed);
943+
if (point == null) {
944+
throw new InvalidSceneSyntaxException("Attribute 'points' must contain semicolon-separated 3D vectors");
945+
}
946+
points.add(point);
947+
}
948+
if (points.size() < 2) {
949+
throw new InvalidSceneSyntaxException("Attribute 'points' must contain at least two points");
950+
}
951+
return points.toArray(new float[0][]);
952+
}
953+
911954
@Nullable
912955
private String getOptionalAttributeValue(MdxJsxElementFields element, String name) {
913956
MdxJsxAttribute attribute = element.getAttribute(name);

src/main/java/com/hfstudio/guidenh/guide/internal/editor/preview/SceneEditorHandleOverlay.java

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@ public class SceneEditorHandleOverlay {
7171
private final Vector3f handleWorldScratch = new Vector3f();
7272
private final Vector3f planeArmAScratch = new Vector3f();
7373
private final Vector3f planeArmBScratch = new Vector3f();
74-
private final Vector3f axisBoundsCenterScratch = new Vector3f();
7574
private final Vector3f axisBoundsTipScratch = new Vector3f();
76-
private final AxisArrowGeometry axisArrowScratch = new AxisArrowGeometry();
7775

7876
public boolean supportsPointHandle(@Nullable SceneEditorElementModel element) {
7977
return getHandleIds(element).length > 0;
@@ -327,18 +325,9 @@ private Vector3f projectWorldPoint(CameraSettings camera, LytRect viewport, floa
327325

328326
private LytRect getAxisHandleBounds(SceneEditorElementModel element, CameraSettings camera, LytRect viewport,
329327
String handleId) {
330-
Vector3f center = projectHandlePoint(element, camera, viewport, CENTER_HANDLE_ID, axisBoundsCenterScratch);
331328
Vector3f tip = projectHandlePoint(element, camera, viewport, handleId, axisBoundsTipScratch);
332-
AxisArrowGeometry geometry = createAxisArrowGeometry(center, tip, axisArrowScratch);
333-
float minX = Math.min(tip.x, Math.min(geometry.leftX, geometry.rightX));
334-
float minY = Math.min(tip.y, Math.min(geometry.leftY, geometry.rightY));
335-
float maxX = Math.max(tip.x, Math.max(geometry.leftX, geometry.rightX));
336-
float maxY = Math.max(tip.y, Math.max(geometry.leftY, geometry.rightY));
337-
return new LytRect(
338-
(int) Math.floor(minX) - 2,
339-
(int) Math.floor(minY) - 2,
340-
Math.max(AXIS_HANDLE_DIAMETER, (int) Math.ceil(maxX - minX) + 5),
341-
Math.max(AXIS_HANDLE_DIAMETER, (int) Math.ceil(maxY - minY) + 5));
329+
int radius = Math.max(AXIS_HANDLE_RADIUS, Math.round(ARROW_LENGTH));
330+
return new LytRect(Math.round(tip.x) - radius, Math.round(tip.y) - radius, radius * 2 + 1, radius * 2 + 1);
342331
}
343332

344333
private Vector3f projectPlaneHandlePoint(SceneEditorElementModel element, CameraSettings camera, LytRect viewport,
@@ -433,38 +422,32 @@ private float distanceSqToSegment(float px, float py, float ax, float ay, float
433422
}
434423

435424
private void drawAxisArrow(Vector3f from, Vector3f to, int color) {
436-
AxisArrowGeometry geometry = createAxisArrowGeometry(from, to, axisArrowScratch);
437-
drawFilledTriangle(to.x, to.y, geometry.leftX, geometry.leftY, geometry.rightX, geometry.rightY, color);
438-
}
439-
440-
private AxisArrowGeometry createAxisArrowGeometry(Vector3f from, Vector3f to, AxisArrowGeometry dest) {
441425
float dx = to.x - from.x;
442426
float dy = to.y - from.y;
443427
float length = (float) Math.sqrt(dx * dx + dy * dy);
444428
if (length < 1e-4f) {
445-
return dest.set(to.x, to.y, to.x, to.y, to.x, to.y);
429+
return;
446430
}
447431
float ux = dx / length;
448432
float uy = dy / length;
449433
float px = -uy;
450434
float py = ux;
451435
float arrowLength = Math.min(ARROW_LENGTH, Math.max(3f, length * 0.55f));
452-
if (arrowLength > length) {
453-
arrowLength = length;
454-
}
436+
arrowLength = Math.min(arrowLength, length);
455437
float arrowHalfWidth = Math.min(ARROW_HALF_WIDTH, Math.max(2f, arrowLength * 0.5f));
456438
float baseX = to.x - ux * arrowLength;
457439
float baseY = to.y - uy * arrowLength;
458-
return dest.set(
459-
baseX + px * arrowHalfWidth,
460-
baseY + py * arrowHalfWidth,
461-
baseX - px * arrowHalfWidth,
462-
baseY - py * arrowHalfWidth,
463-
baseX,
464-
baseY);
465-
}
440+
float tipZ = 0.08f;
441+
float baseZ = -0.08f;
442+
float leftX = baseX + px * arrowHalfWidth;
443+
float leftY = baseY + py * arrowHalfWidth;
444+
float rightX = baseX - px * arrowHalfWidth;
445+
float rightY = baseY - py * arrowHalfWidth;
446+
float upX = baseX + ux * arrowHalfWidth * 0.35f;
447+
float upY = baseY + uy * arrowHalfWidth * 0.35f;
448+
float downX = baseX - ux * arrowHalfWidth * 0.35f;
449+
float downY = baseY - uy * arrowHalfWidth * 0.35f;
466450

467-
private void drawFilledTriangle(float ax, float ay, float bx, float by, float cx, float cy, int color) {
468451
float a = ((color >>> 24) & 0xFF) / 255f;
469452
float r = ((color >>> 16) & 0xFF) / 255f;
470453
float g = ((color >>> 8) & 0xFF) / 255f;
@@ -477,16 +460,24 @@ private void drawFilledTriangle(float ax, float ay, float bx, float by, float cx
477460
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
478461
GL11.glColor4f(r, g, b, a);
479462
GL11.glBegin(GL11.GL_TRIANGLES);
480-
GL11.glVertex3f(ax, ay, 0f);
481-
GL11.glVertex3f(bx, by, 0f);
482-
GL11.glVertex3f(cx, cy, 0f);
463+
drawTriangle(to.x, to.y, tipZ, leftX, leftY, baseZ, upX, upY, 0f);
464+
drawTriangle(to.x, to.y, tipZ, upX, upY, 0f, rightX, rightY, baseZ);
465+
drawTriangle(to.x, to.y, tipZ, rightX, rightY, baseZ, downX, downY, 0f);
466+
drawTriangle(to.x, to.y, tipZ, downX, downY, 0f, leftX, leftY, baseZ);
483467
GL11.glEnd();
484468
} finally {
485469
GL11.glPopAttrib();
486470
GL11.glColor4f(1f, 1f, 1f, 1f);
487471
}
488472
}
489473

474+
private void drawTriangle(float ax, float ay, float az, float bx, float by, float bz, float cx, float cy,
475+
float cz) {
476+
GL11.glVertex3f(ax, ay, az);
477+
GL11.glVertex3f(bx, by, bz);
478+
GL11.glVertex3f(cx, cy, cz);
479+
}
480+
490481
private void drawLine(Vector3f from, Vector3f to, int color, float lineWidth) {
491482
float a = ((color >>> 24) & 0xFF) / 255f;
492483
float r = ((color >>> 16) & 0xFF) / 255f;
@@ -509,27 +500,4 @@ private void drawLine(Vector3f from, Vector3f to, int color, float lineWidth) {
509500
}
510501
}
511502

512-
public static class AxisArrowGeometry {
513-
514-
private float leftX;
515-
private float leftY;
516-
private float rightX;
517-
private float rightY;
518-
@SuppressWarnings("unused")
519-
private float baseX;
520-
@SuppressWarnings("unused")
521-
private float baseY;
522-
523-
private AxisArrowGeometry() {}
524-
525-
private AxisArrowGeometry set(float leftX, float leftY, float rightX, float rightY, float baseX, float baseY) {
526-
this.leftX = leftX;
527-
this.leftY = leftY;
528-
this.rightX = rightX;
529-
this.rightY = rightY;
530-
this.baseX = baseX;
531-
this.baseY = baseY;
532-
return this;
533-
}
534-
}
535503
}

src/main/java/com/hfstudio/guidenh/guide/internal/editor/preview/SceneEditorPreviewBridge.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,26 @@ public void rebuildScene(SceneEditorSession session, LytGuidebookScene scene,
5252
if (scene == null) {
5353
return;
5454
}
55+
int ponderTick = scene.getPonderCurrentTickForExport();
56+
boolean ponderPaused = scene.isPonderPausedForPreviewRestore();
57+
boolean ponderFinished = scene.isPonderFinishedForPreviewRestore();
5558
scene.getAnnotations()
5659
.clear();
5760
scene.setHoveredStructureLibHatch(null);
5861
scene.setHoveredBlock(null);
5962
scene.setHoveredEntity(null);
6063
scene.clearAnnotationHover();
6164
scene.setStructureLibSceneMetadata(null);
65+
scene.clearPonderDataForPreviewRebuild();
6266
scene.setLevel(new GuidebookLevel());
6367
scene.setReserveBottomControlArea(false);
6468
scene.setForceOriginAxesVisible(true);
6569
scene.setVisibleLayerSliderEnabled(
6670
session.getSceneModel()
6771
.isAllowLayerSlider() || ModConfig.ui.sceneLayerSliderEnabled);
6872
sceneNodePreviewApplier.apply(session, scene, structureLibSelectionOverride);
73+
scene.initializePonderTimelineBaseline();
74+
scene.restorePonderPreviewState(ponderTick, ponderPaused, ponderFinished);
6975
}
7076

7177
private void applyExportCamera(CameraSettings camera, SceneEditorSceneModel model) {

0 commit comments

Comments
 (0)