implement world factory
This commit is contained in:
@@ -18,13 +18,16 @@ public class ModelLibrary {
|
||||
public final Model groundModel;
|
||||
public final Model unitCubeModel;
|
||||
|
||||
// new: town-related primitives
|
||||
public final Model houseBlockModel;
|
||||
public final Model pathTileModel;
|
||||
|
||||
public ModelLibrary() {
|
||||
// ground texture
|
||||
// --- ground texture + model (unchanged) ---
|
||||
groundTexture = new Texture(Gdx.files.internal("textures/paving.png"));
|
||||
groundTexture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||
groundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
|
||||
|
||||
// ground model (32x32 plane)
|
||||
float halfSize = 32f;
|
||||
float tileScale = 16f;
|
||||
|
||||
@@ -52,17 +55,48 @@ public class ModelLibrary {
|
||||
);
|
||||
groundModel = builder.end();
|
||||
|
||||
// a generic 2x2x2 cube model (can be reused for buildings, crates, etc.)
|
||||
// generic 2x2x2 cube
|
||||
unitCubeModel = builder.createBox(
|
||||
2f, 2f, 2f,
|
||||
new Material(ColorAttribute.createDiffuse(1f, 1f, 1f, 1f)),
|
||||
VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal
|
||||
);
|
||||
|
||||
// simple “blocky house” primitive: 4x3x4
|
||||
houseBlockModel = builder.createBox(
|
||||
4f, 3f, 4f,
|
||||
new Material(ColorAttribute.createDiffuse(0.9f, 0.8f, 0.7f, 1f)),
|
||||
VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal
|
||||
);
|
||||
|
||||
// flat path tile (2D quad slightly above ground)
|
||||
builder.begin();
|
||||
Material pathMat = new Material(
|
||||
ColorAttribute.createDiffuse(0.6f, 0.6f, 0.6f, 1f)
|
||||
);
|
||||
MeshPartBuilder pathMpb = builder.part(
|
||||
"pathTile",
|
||||
GL20.GL_TRIANGLES,
|
||||
VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal,
|
||||
pathMat
|
||||
);
|
||||
float tHalf = 1f; // tile size 4x4
|
||||
float y = 0.01f; // just above ground to avoid z-fighting
|
||||
pathMpb.rect(
|
||||
-tHalf, y, tHalf,
|
||||
tHalf, y, tHalf,
|
||||
tHalf, y, -tHalf,
|
||||
-tHalf, y, -tHalf,
|
||||
0f, 1f, 0f
|
||||
);
|
||||
pathTileModel = builder.end();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
groundModel.dispose();
|
||||
unitCubeModel.dispose();
|
||||
houseBlockModel.dispose();
|
||||
pathTileModel.dispose();
|
||||
groundTexture.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package wtf.beatrice.retrorender.engine;
|
||||
|
||||
import com.badlogic.gdx.graphics.g3d.ModelInstance;
|
||||
|
||||
public class TownFactory {
|
||||
|
||||
private final ModelLibrary models;
|
||||
|
||||
public TownFactory(ModelLibrary models) {
|
||||
this.models = models;
|
||||
}
|
||||
|
||||
public WorldObject createHouse(String id, float x, float z) {
|
||||
ModelInstance inst = new ModelInstance(models.houseBlockModel);
|
||||
// houseBlockModel is 4x3x4 → center at y=1.5
|
||||
inst.transform.setToTranslation(x, 1.5f, z);
|
||||
|
||||
// collider roughly matches the visual: halfExtents = (2,1.5,2)
|
||||
Collider col = Collider.box(2f, 1.5f, 2f);
|
||||
|
||||
WorldObject obj = new WorldObject(id, inst, col);
|
||||
obj.staticObject = true;
|
||||
obj.castsShadow = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
public WorldObject createCrate(String id, float x, float z) {
|
||||
ModelInstance inst = new ModelInstance(models.unitCubeModel);
|
||||
// unit cube is 2x2x2 → center at y=1
|
||||
inst.transform.setToTranslation(x, 1f, z);
|
||||
|
||||
Collider col = Collider.box(1f, 1f, 1f);
|
||||
WorldObject obj = new WorldObject(id, inst, col);
|
||||
obj.staticObject = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
public WorldObject createPathTile(String id, float x, float z) {
|
||||
ModelInstance inst = new ModelInstance(models.pathTileModel);
|
||||
inst.transform.setToTranslation(x, 0f, z);
|
||||
// purely visual, no collider
|
||||
WorldObject obj = new WorldObject(id, inst, Collider.none());
|
||||
obj.staticObject = true;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package wtf.beatrice.retrorender.engine;
|
||||
|
||||
import com.badlogic.gdx.graphics.g3d.Environment;
|
||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
||||
import com.badlogic.gdx.graphics.g3d.ModelInstance;
|
||||
import com.badlogic.gdx.math.Matrix4;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
|
||||
@@ -15,6 +16,7 @@ public class World3D {
|
||||
private final WorldObject ground;
|
||||
private final List<WorldObject> objects = new ArrayList<>();
|
||||
|
||||
private final TownFactory townFactory;
|
||||
|
||||
private final Vector3 tmpWorld = new Vector3();
|
||||
private final Vector3 tmpFeet = new Vector3();
|
||||
@@ -29,43 +31,76 @@ public class World3D {
|
||||
|
||||
public World3D(ModelLibrary models) {
|
||||
this.models = models;
|
||||
this.townFactory = new TownFactory(models);
|
||||
|
||||
// --- ground ---
|
||||
ground = new WorldObject(
|
||||
"ground",
|
||||
new com.badlogic.gdx.graphics.g3d.ModelInstance(models.groundModel),
|
||||
Collider.none() // treat plane as baseHeight = 0, not as a collider
|
||||
new ModelInstance(models.groundModel),
|
||||
Collider.none()
|
||||
);
|
||||
ground.staticObject = true;
|
||||
|
||||
// --- some cubes (temporary test geometry) ---
|
||||
addCube("center", 0f, 1f, 0f);
|
||||
addCube("cube-ne", 8f, 1f, 8f);
|
||||
addCube("cube-nw", -8f, 1f, 8f);
|
||||
addCube("cube-se", 8f, 1f, -8f);
|
||||
addCube("cube-sw", -8f, 1f, -8f);
|
||||
|
||||
WorldObject pillar = addCube("pillar", 0f, 3f, -10f);
|
||||
// scale pillar’s transform (purely visual)
|
||||
pillar.instance.transform
|
||||
.setToScaling(1f, 3f, 1f)
|
||||
.translate(0f, 3f, -10f);
|
||||
// collider is still 1x1x1, you can adjust collider.halfExtents here if needed
|
||||
// --- build a tiny town layout instead of random cubes ---
|
||||
buildTestTown();
|
||||
}
|
||||
|
||||
private WorldObject addCube(String id, float x, float y, float z) {
|
||||
var instance = new com.badlogic.gdx.graphics.g3d.ModelInstance(models.unitCubeModel);
|
||||
instance.transform.setToTranslation(x, y, z);
|
||||
|
||||
// cube is 2x2x2, so half extents = 1
|
||||
Collider collider = Collider.box(1f, 1f, 1f);
|
||||
|
||||
WorldObject obj = new WorldObject(id, instance, collider);
|
||||
obj.staticObject = true;
|
||||
private void addObject(WorldObject obj) {
|
||||
objects.add(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void buildTestTown() {
|
||||
float tileSize = 2f; // world units per “map tile”
|
||||
|
||||
// Simple 7x7 layout:
|
||||
// H = house, P = path, . = empty
|
||||
String[] layout = {
|
||||
".............",
|
||||
"..H.C.....H..",
|
||||
"..P.......P..",
|
||||
"..P.......P..",
|
||||
"..P.......P..",
|
||||
"..P.......P..",
|
||||
"..P.......P..",
|
||||
"..P.......P..",
|
||||
"..H.......H..",
|
||||
"............."
|
||||
};
|
||||
|
||||
int rows = layout.length;
|
||||
int cols = layout[0].length();
|
||||
|
||||
float offsetX = -(cols - 1) * tileSize * 0.5f;
|
||||
float offsetZ = -(rows - 1) * tileSize * 0.5f;
|
||||
|
||||
for (int row = 0; row < rows; row++) {
|
||||
String line = layout[row];
|
||||
for (int col = 0; col < cols; col++) {
|
||||
char c = line.charAt(col);
|
||||
|
||||
float x = offsetX + col * tileSize;
|
||||
float z = offsetZ + row * tileSize;
|
||||
|
||||
switch (c) {
|
||||
case 'H':
|
||||
addObject(townFactory.createHouse("house_" + row + "_" + col, x, z));
|
||||
break;
|
||||
case 'P':
|
||||
addObject(townFactory.createPathTile("path_" + row + "_" + col, x, z));
|
||||
break;
|
||||
case 'C':
|
||||
addObject(townFactory.createCrate("crate_" + row + "_" + col, x, z));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe put a crate in the middle
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void update(float delta) {
|
||||
// here you can update objects that animate / move
|
||||
for (WorldObject obj : objects) {
|
||||
|
||||
@@ -21,7 +21,6 @@ public class WorldObject {
|
||||
}
|
||||
|
||||
public void update(float delta) {
|
||||
instance.transform.rotate(Vector3.Y, delta * 20f);
|
||||
// default: do nothing
|
||||
// you can subclass or add strategies later for rotating, animating, AI, etc.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user