implement world factory
This commit is contained in:
@@ -18,13 +18,16 @@ public class ModelLibrary {
|
|||||||
public final Model groundModel;
|
public final Model groundModel;
|
||||||
public final Model unitCubeModel;
|
public final Model unitCubeModel;
|
||||||
|
|
||||||
|
// new: town-related primitives
|
||||||
|
public final Model houseBlockModel;
|
||||||
|
public final Model pathTileModel;
|
||||||
|
|
||||||
public ModelLibrary() {
|
public ModelLibrary() {
|
||||||
// ground texture
|
// --- ground texture + model (unchanged) ---
|
||||||
groundTexture = new Texture(Gdx.files.internal("textures/paving.png"));
|
groundTexture = new Texture(Gdx.files.internal("textures/paving.png"));
|
||||||
groundTexture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
groundTexture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||||
groundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
|
groundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
|
||||||
|
|
||||||
// ground model (32x32 plane)
|
|
||||||
float halfSize = 32f;
|
float halfSize = 32f;
|
||||||
float tileScale = 16f;
|
float tileScale = 16f;
|
||||||
|
|
||||||
@@ -52,17 +55,48 @@ public class ModelLibrary {
|
|||||||
);
|
);
|
||||||
groundModel = builder.end();
|
groundModel = builder.end();
|
||||||
|
|
||||||
// a generic 2x2x2 cube model (can be reused for buildings, crates, etc.)
|
// generic 2x2x2 cube
|
||||||
unitCubeModel = builder.createBox(
|
unitCubeModel = builder.createBox(
|
||||||
2f, 2f, 2f,
|
2f, 2f, 2f,
|
||||||
new Material(ColorAttribute.createDiffuse(1f, 1f, 1f, 1f)),
|
new Material(ColorAttribute.createDiffuse(1f, 1f, 1f, 1f)),
|
||||||
VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal
|
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() {
|
public void dispose() {
|
||||||
groundModel.dispose();
|
groundModel.dispose();
|
||||||
unitCubeModel.dispose();
|
unitCubeModel.dispose();
|
||||||
|
houseBlockModel.dispose();
|
||||||
|
pathTileModel.dispose();
|
||||||
groundTexture.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.Environment;
|
||||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
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.Matrix4;
|
||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ public class World3D {
|
|||||||
private final WorldObject ground;
|
private final WorldObject ground;
|
||||||
private final List<WorldObject> objects = new ArrayList<>();
|
private final List<WorldObject> objects = new ArrayList<>();
|
||||||
|
|
||||||
|
private final TownFactory townFactory;
|
||||||
|
|
||||||
private final Vector3 tmpWorld = new Vector3();
|
private final Vector3 tmpWorld = new Vector3();
|
||||||
private final Vector3 tmpFeet = new Vector3();
|
private final Vector3 tmpFeet = new Vector3();
|
||||||
@@ -29,43 +31,76 @@ public class World3D {
|
|||||||
|
|
||||||
public World3D(ModelLibrary models) {
|
public World3D(ModelLibrary models) {
|
||||||
this.models = models;
|
this.models = models;
|
||||||
|
this.townFactory = new TownFactory(models);
|
||||||
|
|
||||||
// --- ground ---
|
// --- ground ---
|
||||||
ground = new WorldObject(
|
ground = new WorldObject(
|
||||||
"ground",
|
"ground",
|
||||||
new com.badlogic.gdx.graphics.g3d.ModelInstance(models.groundModel),
|
new ModelInstance(models.groundModel),
|
||||||
Collider.none() // treat plane as baseHeight = 0, not as a collider
|
Collider.none()
|
||||||
);
|
);
|
||||||
ground.staticObject = true;
|
ground.staticObject = true;
|
||||||
|
|
||||||
// --- some cubes (temporary test geometry) ---
|
// --- build a tiny town layout instead of random cubes ---
|
||||||
addCube("center", 0f, 1f, 0f);
|
buildTestTown();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private WorldObject addCube(String id, float x, float y, float z) {
|
private void addObject(WorldObject obj) {
|
||||||
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;
|
|
||||||
objects.add(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) {
|
public void update(float delta) {
|
||||||
// here you can update objects that animate / move
|
// here you can update objects that animate / move
|
||||||
for (WorldObject obj : objects) {
|
for (WorldObject obj : objects) {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ public class WorldObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update(float delta) {
|
public void update(float delta) {
|
||||||
instance.transform.rotate(Vector3.Y, delta * 20f);
|
|
||||||
// default: do nothing
|
// default: do nothing
|
||||||
// you can subclass or add strategies later for rotating, animating, AI, etc.
|
// you can subclass or add strategies later for rotating, animating, AI, etc.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user