Skip to content

Commit f1f8077

Browse files
Merge pull request #79 from ArtifactForms/working2
Working2
2 parents 1b0fd0f + 7809b98 commit f1f8077

10 files changed

Lines changed: 615 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package engine.demos.ray;
2+
3+
import engine.components.Component;
4+
import math.Ray3f;
5+
6+
public interface RaycastComponent extends Component {
7+
8+
/**
9+
* Tests the given ray against this component.
10+
*
11+
* @param ray the ray in world space
12+
* @return a RaycastHit if an intersection occurred, otherwise null
13+
*/
14+
RaycastHit raycast(Ray3f ray);
15+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package engine.demos.ray;
2+
3+
import engine.scene.SceneNode;
4+
import math.Vector3f;
5+
6+
public class RaycastHit {
7+
8+
private final SceneNode target;
9+
private final Vector3f point;
10+
private final float distance;
11+
12+
public RaycastHit(SceneNode target, Vector3f point, float distance) {
13+
this.target = target;
14+
this.point = point;
15+
this.distance = distance;
16+
}
17+
18+
public SceneNode getTarget() {
19+
return target;
20+
}
21+
22+
public Vector3f getPoint() {
23+
return point;
24+
}
25+
26+
public float getDistance() {
27+
return distance;
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package engine.demos.ray;
2+
3+
import engine.scene.SceneNode;
4+
import engine.scene.SceneNodeVisitor;
5+
import math.Ray3f;
6+
7+
public final class RaycastQuery implements SceneNodeVisitor {
8+
9+
private final Ray3f ray;
10+
private RaycastHit closestHit;
11+
12+
public RaycastQuery(Ray3f ray) {
13+
this.ray = ray;
14+
}
15+
16+
@Override
17+
public void visit(SceneNode node) {
18+
for (RaycastComponent rc : node.getComponents(RaycastComponent.class)) {
19+
RaycastHit hit = rc.raycast(ray);
20+
if (hit != null) {
21+
if (closestHit == null || hit.getDistance() < closestHit.getDistance()) {
22+
closestHit = hit;
23+
}
24+
}
25+
}
26+
}
27+
28+
public RaycastHit getResult() {
29+
return closestHit;
30+
}
31+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package engine.demos.ray;
2+
3+
import engine.components.Transform;
4+
import engine.scene.camera.Camera;
5+
import math.Ray3f;
6+
import math.Vector3f;
7+
8+
public class Raycaster {
9+
10+
public static Ray3f crossHairRay(Camera camera) {
11+
Transform t = camera.getTransform();
12+
13+
Vector3f origin = t.getPosition();
14+
Vector3f direction = t.getForward();
15+
16+
return new Ray3f(origin, direction);
17+
}
18+
19+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package engine.resources;
2+
3+
import java.awt.image.BufferedImage;
4+
import java.io.BufferedReader;
5+
import java.io.File;
6+
import java.io.FileReader;
7+
import java.io.IOException;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
import javax.imageio.ImageIO;
12+
13+
import engine.render.Material;
14+
15+
public class MaterialLoader {
16+
private static final String KEY_NEW_MATERIAL = "newmtl";
17+
private static final String KEY_SHININESS = "Ns";
18+
private static final String KEY_AMBIENT_COLOR = "Ka";
19+
private static final String KEY_DIFFUSE_COLOR = "Kd";
20+
private static final String KEY_SPECULAR_COLOR = "Ks";
21+
private static final String KEY_DISSOLVE = "d"; // opacity
22+
private static final String KEY_DIFFUSE_MAP = "map_Kd";
23+
private static final String KEY_OPACITY_MAP = "map_d";
24+
25+
private Map<String, Material> materials = new HashMap<>();
26+
private String directoryPath;
27+
28+
public Map<String, Material> loadMaterials(String filePath) throws IOException {
29+
directoryPath = filePath.substring(0, filePath.lastIndexOf('/'));
30+
BufferedReader reader = new BufferedReader(new FileReader(filePath));
31+
Material currentMaterial = null;
32+
33+
String line;
34+
while ((line = reader.readLine()) != null) {
35+
String[] parts = line.split("\\s+", 2);
36+
String keyword = parts[0];
37+
38+
switch (keyword) {
39+
case KEY_NEW_MATERIAL:
40+
currentMaterial = new Material();
41+
currentMaterial.setName(parts[1]);
42+
materials.put(parts[1], currentMaterial);
43+
break;
44+
case KEY_DIFFUSE_COLOR:
45+
currentMaterial.setDiffuse(parseColor(parts[1]));
46+
break;
47+
case KEY_SPECULAR_COLOR:
48+
currentMaterial.setSpecular(parseColor(parts[1]));
49+
break;
50+
case "Ns":
51+
currentMaterial.setShininess(Float.parseFloat(parts[1]));
52+
break;
53+
case KEY_DISSOLVE:
54+
currentMaterial.setOpacity(Float.parseFloat(parts[1]));
55+
break;
56+
case KEY_DIFFUSE_MAP:
57+
String file = parts[1];
58+
59+
System.out.println(parts[1]);
60+
61+
try {
62+
BufferedImage image;
63+
image = ImageIO.read(new File(directoryPath + "/" + file));
64+
Texture texture = TextureManager.getInstance().createTexture(image);
65+
66+
currentMaterial.setDiffuseTexture(texture);
67+
} catch (IOException e) {
68+
// TODO Auto-generated catch block
69+
e.printStackTrace();
70+
}
71+
72+
break;
73+
74+
case KEY_OPACITY_MAP:
75+
String file1 = parts[1];
76+
77+
System.out.println(parts[1]);
78+
79+
try {
80+
BufferedImage image;
81+
image = ImageIO.read(new File(directoryPath + "/" + file1));
82+
Texture opactityMap = TextureManager.getInstance().createTexture(image);
83+
84+
currentMaterial.setOpacityMap(opactityMap);
85+
} catch (IOException e) {
86+
// TODO Auto-generated catch block
87+
e.printStackTrace();
88+
}
89+
break;
90+
}
91+
}
92+
93+
reader.close();
94+
return materials;
95+
}
96+
97+
private float[] parseColor(String line) {
98+
String[] values = line.split(" ");
99+
float red = Float.parseFloat(values[0]);
100+
float green = Float.parseFloat(values[1]);
101+
float blue = Float.parseFloat(values[2]);
102+
return new float[] {red, green, blue};
103+
}
104+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package engine.resources;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import engine.render.Material;
7+
import mesh.Mesh3D;
8+
import mesh.SubMesh;
9+
10+
public class Model {
11+
private String name;
12+
private Mesh3D mesh;
13+
private List<SubMesh> meshes;
14+
private List<Material> materials;
15+
16+
public Model(String name) {
17+
if (name == null) {
18+
throw new IllegalArgumentException("Name cannot be null");
19+
}
20+
this.name = name;
21+
mesh = new Mesh3D();
22+
meshes = new ArrayList<SubMesh>();
23+
materials = new ArrayList<Material>();
24+
}
25+
26+
public void addSubMesh(SubMesh mesh) {
27+
if (mesh == null) {
28+
throw new IllegalArgumentException("Mesh cannot be null.");
29+
}
30+
meshes.add(mesh);
31+
}
32+
33+
public void addMaterial(Material material) {
34+
if (material == null) {
35+
throw new IllegalArgumentException("Material cannot be null.");
36+
}
37+
// material.setUseLighting(false);
38+
materials.add(material);
39+
}
40+
41+
public String getName() {
42+
return name;
43+
}
44+
45+
public Mesh3D getMesh() {
46+
return mesh;
47+
}
48+
49+
public void setMesh(Mesh3D mesh) {
50+
this.mesh = mesh;
51+
}
52+
53+
public List<SubMesh> getSubMeshes() {
54+
return meshes;
55+
}
56+
57+
public void setUseLighting(boolean useLighting) {
58+
for (Material material : materials) {
59+
material.setUseLighting(useLighting);
60+
}
61+
}
62+
63+
public List<Material> getMaterials() {
64+
return materials;
65+
}
66+
67+
public Material getMaterial(String name) {
68+
for (int i = 0; i < materials.size(); i++) {
69+
Material material = materials.get(i);
70+
if (material.getName().equals(name)) return material;
71+
}
72+
// Exception??
73+
return null;
74+
}
75+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package engine.resources;
2+
3+
public class ModelLoader {
4+
5+
// Core method to load models
6+
public static Model load(String filePath, String extension) {
7+
// String extension = getFileExtension(filePath);
8+
ModelLoaderStrategy loader = getLoaderForExtension(extension);
9+
return loader.load(filePath);
10+
}
11+
12+
// Helper to get appropriate loader
13+
private static ModelLoaderStrategy getLoaderForExtension(String extension) {
14+
switch (extension.toLowerCase()) {
15+
case "obj":
16+
return new OBJLoader();
17+
case "gltf":
18+
return new GLTFLoader();
19+
// case "fbx":
20+
// return new FBXLoader();
21+
default:
22+
throw new UnsupportedOperationException("Unsupported format: " + extension);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)