Skip to content

Commit 31c67cc

Browse files
Teardown models (DEV)
1 parent b50a0e8 commit 31c67cc

File tree

7 files changed

+151
-21
lines changed

7 files changed

+151
-21
lines changed

pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@
9595
<artifactId>gvox-java</artifactId>
9696
<version>1.2.5-PRE3</version>
9797
</dependency>
98+
99+
<dependency>
100+
<groupId>xerces</groupId>
101+
<artifactId>xercesImpl</artifactId>
102+
<version>2.12.2</version>
103+
</dependency>
98104
</dependencies>
99105

100106
</project>

src/main/java/de/fabulousfox/engine/Model.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ public class Model {
1515
private final int id;
1616

1717
private final Vector3f position;
18+
private final Vector3f rotation;
1819

1920
private final Texture3D data;
2021
private final int sizeX;
2122
private final int sizeY;
2223
private final int sizeZ;
2324

24-
public Model(Texture3D data, Vector3f position, int sizeX, int sizeY, int sizeZ) {
25+
public Model(Texture3D data, Vector3f position, Vector3f rotation, int sizeX, int sizeY, int sizeZ) {
2526
this.position = position;
27+
this.rotation = rotation;
2628

2729
this.id = idCounter;
2830
idCounter++;
@@ -33,13 +35,18 @@ public Model(Texture3D data, Vector3f position, int sizeX, int sizeY, int sizeZ)
3335
this.sizeZ = sizeZ;
3436
}
3537

38+
public Model(Texture3D data, Vector3f position, int sizeX, int sizeY, int sizeZ){
39+
this(data, position, new Vector3f(0, 0, 0), sizeX, sizeY, sizeZ);
40+
}
41+
3642
public void prepareShader(Shader shader) {
3743
shader.setMatrix4f("model", new Matrix4f().translate(this.position));
3844
shader.setInt("dataContainer", 5);
3945
shader.setInt("sizeX", this.sizeX);
4046
shader.setInt("sizeY", this.sizeY);
4147
shader.setInt("sizeZ", this.sizeZ);
4248
shader.setVector3f("modelPosition", this.position);
49+
shader.setVector3f("modelRotation", this.rotation);
4350
shader.setFloat("voxelSize", VOXEL_SIZE);
4451
}
4552

src/main/java/de/fabulousfox/engine/Renderer.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,13 @@ public Renderer(int windowWidth, int windowHeight, String windowTitle) {
368368
System.out.println("Initializing World...");
369369

370370
models = new ArrayList<>();
371-
models.addAll(VoxelLoader.load("/models/vehicle/boat/mediumboat.vox"));
371+
Vector3f spawn = new Vector3f(0, 0, 0);
372+
try {
373+
models.addAll(VoxelLoader.loadTeardown(spawn, "C:/Users/fabif/Documents/Teardown/mods/montagna del castello Copy/main.xml"));
374+
} catch (Exception e) {
375+
e.printStackTrace();
376+
}
377+
//models.addAll(VoxelLoader.load("/models/vehicle/boat/mediumboat.vox"));
372378
//models.addAll(VoxelLoader.load("/models/menger.vox"));
373379
//models.addAll(VoxelLoader.load("/models/castle.vox"));
374380
//models.addAll(VoxelLoader.load("/models/castle_full.vox"));

src/main/java/de/fabulousfox/engine/VoxelLoader.java

+100-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,21 @@
1414
import de.fabulousfox.libs.voxfileparser.*;
1515
import de.fabulousfox.libs.voxfileparser.chunk.VoxRGBAChunk;
1616
import org.joml.Vector3f;
17-
17+
import org.w3c.dom.Document;
18+
import org.w3c.dom.Element;
19+
import org.w3c.dom.Node;
20+
import org.w3c.dom.NodeList;
21+
import org.xml.sax.SAXException;
22+
23+
import javax.xml.parsers.DocumentBuilder;
24+
import javax.xml.parsers.DocumentBuilderFactory;
25+
import javax.xml.parsers.ParserConfigurationException;
1826
import java.awt.*;
27+
import java.io.File;
1928
import java.io.FileInputStream;
2029
import java.io.IOException;
2130
import java.util.ArrayList;
31+
import java.util.HashMap;
2232
import java.util.List;
2333
import java.util.concurrent.ConcurrentLinkedQueue;
2434

@@ -214,4 +224,93 @@ public static List<Model> loadGVOX(String path) {
214224

215225
return List.of();
216226
}
227+
228+
private static Node firstNodeListElementOrNull(NodeList nodeList) {
229+
if (nodeList.getLength() > 0) {
230+
return nodeList.item(0);
231+
} else {
232+
return null;
233+
}
234+
}
235+
236+
private static int totalVoxBoxes = 0;
237+
private static int totalVoxBoxesCount = 0;
238+
239+
private static void traverseNodes(Vector3f posOffset, Vector3f rotationOffset, Node thisNode, List<Model> models) throws NumberFormatException {
240+
if (thisNode.getNodeType() != Node.ELEMENT_NODE) return;
241+
Element thisElement = (Element) thisNode;
242+
243+
Vector3f pOffset = new Vector3f(posOffset);
244+
Vector3f rOffset = new Vector3f(rotationOffset);
245+
int[] size = new int[3];
246+
String[] pOffsetString = thisElement.getAttribute("pos").split(" ");
247+
String[] rOffsetString = thisElement.getAttribute("rot").split(" ");
248+
String[] sizeString = thisElement.getAttribute("size").split(" ");
249+
if(pOffsetString.length == 3) {
250+
pOffset.x += Float.parseFloat(pOffsetString[0]);
251+
pOffset.y += Float.parseFloat(pOffsetString[1]);
252+
pOffset.z += Float.parseFloat(pOffsetString[2]);
253+
}
254+
if(rOffsetString.length == 3) {
255+
rOffset.x += Float.parseFloat(rOffsetString[0]);
256+
rOffset.y += Float.parseFloat(rOffsetString[1]);
257+
rOffset.z += Float.parseFloat(rOffsetString[2]);
258+
}
259+
if(sizeString.length == 3) {
260+
size[0] = Integer.parseInt(sizeString[0]);
261+
size[1] = Integer.parseInt(sizeString[1]);
262+
size[2] = Integer.parseInt(sizeString[2]);
263+
}
264+
265+
if(thisElement.getNodeName().equalsIgnoreCase("voxbox")){
266+
Texture3D texture = new Texture3D(size[0], size[1], size[2]);
267+
texture.fill();
268+
texture.create();
269+
270+
models.add(new Model(texture, pOffset.mul(Model.VOXEL_SIZE), rOffset, size[0], size[1], size[2]));
271+
272+
totalVoxBoxesCount++;
273+
System.out.println("Progress: " + totalVoxBoxesCount + "/" + totalVoxBoxes + " -> " + 100f * ((float)totalVoxBoxesCount / (float)totalVoxBoxes) + "%");
274+
}
275+
276+
if(thisNode.getChildNodes().getLength() != 0) {
277+
for (int i = 0; i < thisNode.getChildNodes().getLength(); i++) {
278+
traverseNodes(pOffset, rOffset, thisNode.getChildNodes().item(i), models);
279+
}
280+
}
281+
}
282+
283+
public static List<Model> loadTeardown(Vector3f spawnPoint, String pathToXML) throws ParserConfigurationException, IOException, SAXException, NumberFormatException {
284+
List<Model> models = new ArrayList<>();
285+
286+
String[] tempStringArray;
287+
Node tempNode;
288+
289+
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
290+
Document doc = builder.parse(new File(pathToXML));
291+
doc.getDocumentElement().normalize();
292+
293+
Node sceneNode = doc.getElementsByTagName("scene").item(0);
294+
295+
Node spawnPointNode = firstNodeListElementOrNull(doc.getElementsByTagName("spawnpoint"));
296+
if(spawnPointNode != null) {
297+
tempNode = spawnPointNode.getAttributes().getNamedItem("pos");
298+
tempStringArray = tempNode.getTextContent().split(" ");
299+
spawnPoint.x = Float.parseFloat(tempStringArray[0]);
300+
spawnPoint.y = Float.parseFloat(tempStringArray[1]);
301+
spawnPoint.z = Float.parseFloat(tempStringArray[2]);
302+
}
303+
304+
Node worldNode = firstNodeListElementOrNull(doc.getElementsByTagName("group"));
305+
if(worldNode == null) throw new RuntimeException("No world node found");
306+
307+
totalVoxBoxes = doc.getElementsByTagName("voxbox").getLength();
308+
totalVoxBoxesCount = 0;
309+
310+
System.out.println("Traversing nodes... ("+totalVoxBoxes+")");
311+
traverseNodes(new Vector3f(0, 0, 0), new Vector3f(0, 0, 0), worldNode, models);
312+
System.out.println("Done traversing nodes ("+totalVoxBoxes+")");
313+
314+
return models;
315+
}
217316
}

src/main/java/de/fabulousfox/engine/wrapper/Texture3D.java

+22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.lwjgl.BufferUtils;
44

5+
import java.awt.*;
56
import java.nio.ByteBuffer;
67

78
import static org.lwjgl.opengl.GL46.*;
@@ -30,6 +31,27 @@ public void setPixel(int x, int y, int z, int color) {
3031
image.put(address + 3, (byte) ((color >> 24) & 0xFF)); // Alpha component
3132
}
3233

34+
public void fill(){
35+
int defaultColor = new Color(0, 0, 0, 0).getRGB();
36+
int colorRed = new Color(255, 0, 0, 255).getRGB();
37+
int colorGreen = new Color(0, 255, 0, 255).getRGB();
38+
int colorBlue = new Color(0, 0, 255, 255).getRGB();
39+
int colorWhite = new Color(255, 255, 255, 255).getRGB();
40+
41+
for(int x = 0; x < sizeX; x++){
42+
for(int y = 0; y < sizeY; y++){
43+
for(int z = 0; z < sizeZ; z++){
44+
int color = -1;
45+
if(x == 0 || x == sizeX - 1) color = color == -1 ? colorRed : colorWhite;
46+
if(y == 0 || y == sizeY - 1) color = color == -1 ? colorGreen : colorWhite;
47+
if(z == 0 || z == sizeZ - 1) color = color == -1 ? colorBlue : colorWhite;
48+
if(color == -1) color = defaultColor;
49+
setPixel(x, y, z, color);
50+
}
51+
}
52+
}
53+
}
54+
3355
public void create() {
3456
glActiveTexture(GL_TEXTURE5);
3557
texture = glGenTextures();

src/main/resources/shader/model/FRAGMENT.frag

+1-6
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,7 @@ DDAResult raycastDDA(vec3 rayPos, vec3 rayDir, bvec3 mask){
9999
mapPos += rayStep * ivec3(mask);
100100
}
101101

102-
//vec3 pixelPositionAbsolute = modelPosition + (rayPos + rayDir * (length(mapPos - rayPos) - 0.5)) * voxelSize;
103-
//vec3 pos = modelPosition + (vec3(mapPos.x * 2, mapPos.y * 2, sizeZ) - vec3(mapPos)) * voxelSize;
104-
105-
// Model position + voxel position + sub-voxel ray offset
106-
vec3 worldSpacePosition = modelPosition + voxelSize * mapPos;
107-
102+
vec3 worldSpacePosition = modelPosition + voxelSize * (rayPos + rayDir * distance(rayPos, mapPos));
108103
return DDAResult(voxel, mask, distance(worldSpacePosition, position), worldSpacePosition, ao);
109104
}
110105

src/main/resources/shader/model/FRAGMENT_INSIDE.frag

+7-12
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ DDAResult raycastDDA(vec3 rayPos, vec3 rayDir, bvec3 mask){
7676
ivec3 mapPos = ivec3(floor(rayPos + 0.));
7777
vec3 deltaDist = abs(vec3(length(rayDir)) / rayDir);
7878
ivec3 rayStep = ivec3(sign(rayDir));
79-
vec3 sideDist = (sign(rayDir) * (vec3(mapPos) - rayPos) + (sign(rayDir) * 0.5) + 0.5) * deltaDist;
79+
vec3 sideDist = (sign(rayDir) * (vec3(mapPos) - rayPos) + (sign(rayDir) * .5) + .5) * deltaDist;
8080
vec4 voxel = vec4(0.);
8181
float ao = 1.;
8282

@@ -86,15 +86,11 @@ DDAResult raycastDDA(vec3 rayPos, vec3 rayDir, bvec3 mask){
8686
voxel = getVoxelAtXYZ(mapPos.x, mapPos.y, mapPos.z);
8787
if (voxel.a > 0.999){
8888
// AO
89-
vec3 intersectPlane = mapPos + vec3(lessThan(rayDir, vec3(0)));
90-
vec3 endRayPos;
91-
vec2 uv;
92-
vec4 ambient;
93-
ambient = calcVoxelAo(mapPos - rayStep * ivec3(mask), vec3(mask).zxy, vec3(mask).yzx);
94-
endRayPos = rayDir / sum(ivec3(mask) * rayDir) * sum(ivec3(mask) * (mapPos + vec3(lessThan(rayDir, vec3(0))) - rayPos)) + rayPos;
95-
vec2 aouv = mod(vec2(dot(ivec3(mask) * endRayPos.yzx, vec3(1.0)), dot(ivec3(mask) * endRayPos.zxy, vec3(1.0))), vec2(1.0));
89+
vec4 ambient = calcVoxelAo(mapPos - rayStep * ivec3(mask), vec3(mask).zxy, vec3(mask).yzx);
90+
vec3 endRayPos = rayDir / sum(ivec3(mask) * rayDir) * sum(ivec3(mask) * (mapPos + vec3(lessThan(rayDir, vec3(0))) - rayPos)) + rayPos;
91+
vec2 aouv = mod(vec2(dot(ivec3(mask) * endRayPos.yzx, vec3(1.)), dot(ivec3(mask) * endRayPos.zxy, vec3(1.))), vec2(1.));
9692
ao = mix(mix(ambient.z, ambient.w, aouv.x), mix(ambient.y, ambient.x, aouv.x), aouv.y);
97-
ao = pow(ao, 1.0 / 3.0);
93+
ao = pow(ao, 1. / 3.);
9894
break;
9995
}
10096

@@ -103,9 +99,8 @@ DDAResult raycastDDA(vec3 rayPos, vec3 rayDir, bvec3 mask){
10399
mapPos += rayStep * ivec3(mask);
104100
}
105101

106-
vec3 pos = modelPosition + (vec3(mapPos.x * 2, mapPos.y * 2, sizeZ) - vec3(mapPos)) * voxelSize;
107-
108-
return DDAResult(voxel, mask, length(position - pos), pos, ao);
102+
vec3 worldSpacePosition = modelPosition + voxelSize * (rayPos + rayDir * distance(rayPos, mapPos));
103+
return DDAResult(voxel, mask, distance(worldSpacePosition, position), worldSpacePosition, ao);
109104
}
110105

111106
void main(){

0 commit comments

Comments
 (0)