Skip to content

Commit 26945e0

Browse files
Copilotriccardobl
andauthored
Fix InstancedNode losing InstanceNodeControl after deserialization (#2605)
* Initial plan * Fix InstancedNode deserialization - add write/read methods to preserve control Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> * Simplify test to avoid asset dependencies - all tests passing Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> * Address code review feedback - remove redundant test Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
1 parent 657d49a commit 26945e0

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,16 @@ public void onMeshChange(Geometry geom) {
407407
public void onGeometryUnassociated(Geometry geom) {
408408
removeFromInstancedGeometry(geom);
409409
}
410+
411+
@Override
412+
public void write(JmeExporter ex) throws IOException {
413+
super.write(ex);
414+
ex.getCapsule(this).write(control, "control", null);
415+
}
416+
417+
@Override
418+
public void read(JmeImporter im) throws IOException {
419+
super.read(im);
420+
control = (InstancedNodeControl) im.getCapsule(this).readSavable("control", null);
421+
}
410422
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2025 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.scene.instancing;
33+
34+
import com.jme3.asset.AssetManager;
35+
import com.jme3.asset.DesktopAssetManager;
36+
import com.jme3.export.binary.BinaryExporter;
37+
import org.junit.Assert;
38+
import org.junit.Test;
39+
40+
/**
41+
* Verifies that the {@link InstancedNode} class works correctly.
42+
*
43+
* @author copilot
44+
*/
45+
public class InstancedNodeTest {
46+
47+
private static final AssetManager assetManager = new DesktopAssetManager();
48+
49+
/**
50+
* Test that InstancedNode serialization preserves the InstanceNodeControl.
51+
*/
52+
@Test
53+
public void testSerializationPreservesControl() throws Exception {
54+
// Create an InstancedNode
55+
InstancedNode instancedNode = new InstancedNode("test_instanced_node");
56+
57+
// Verify the control exists before serialization
58+
Assert.assertEquals("InstancedNode should have 1 control before serialization",
59+
1, instancedNode.getNumControls());
60+
61+
// Serialize and deserialize
62+
InstancedNode loaded = (InstancedNode) BinaryExporter.saveAndLoad(assetManager, instancedNode);
63+
64+
// Verify the control exists after deserialization
65+
Assert.assertNotNull("Loaded InstancedNode should not be null", loaded);
66+
Assert.assertEquals("InstancedNode should have 1 control after deserialization",
67+
1, loaded.getNumControls());
68+
69+
// Verify the control is the right type
70+
Assert.assertNotNull("Control should not be null", loaded.getControl(0));
71+
}
72+
}

0 commit comments

Comments
 (0)