fix aabb-road intersection test
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
488ce9fd21
commit
93aca059d3
@ -1923,6 +1923,7 @@ Properly layout roads along town points in TownLayout
|
||||
Town generates a structure -- scaffolding for doing it across roads
|
||||
Structures create foundations in terrain voxels
|
||||
Place buildings along roads
|
||||
Fix town placement structure-road intersection test
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.renderer.pipelines.debug;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.AABBd;
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
@ -40,6 +41,9 @@ import electrosphere.renderer.pipelines.RenderPipeline;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.macro.civilization.road.Road;
|
||||
import electrosphere.server.macro.structure.VirtualStructure;
|
||||
import electrosphere.util.math.SpatialMathUtils;
|
||||
|
||||
/**
|
||||
* Pipeline for rendering content to assist debugging
|
||||
@ -180,6 +184,17 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//Draw town data
|
||||
if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawGridAlignment()){
|
||||
for(VirtualStructure struct : Globals.serverState.realmManager.first().getMacroData().getStructures()){
|
||||
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, struct.getAABB(), AssetDataStrings.TEXTURE_BLUE_TRANSPARENT);
|
||||
}
|
||||
for(Road road : Globals.serverState.realmManager.first().getMacroData().getRoads()){
|
||||
DebugContentPipeline.renderTube(openGLState, renderPipelineState, modelTransformMatrix, road.getPoint1(), road.getPoint2(), road.getRadius(), AssetDataStrings.TEXTURE_BLUE_TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
//update pipeline state to use mats again
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
|
||||
@ -416,6 +431,55 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an area select
|
||||
* @param openGLState The opengl state
|
||||
* @param renderPipelineState The render pipeline state
|
||||
* @param modelTransformMatrix The model transform matrix
|
||||
* @param areaSelection The area selection
|
||||
*/
|
||||
static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AABBd aabb, String texturePath){
|
||||
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE);
|
||||
if(model != null){
|
||||
Texture texture = Globals.assetManager.fetchTexture(texturePath);
|
||||
if(texture != null){
|
||||
texture.bind(openGLState);
|
||||
}
|
||||
//calculate camera-modified vector3d
|
||||
Vector3d cameraModifiedPosition = new Vector3d(aabb.minX,aabb.minY,aabb.minZ).lerp(new Vector3d(aabb.maxX,aabb.maxY,aabb.maxZ),0.5).sub(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
|
||||
modelTransformMatrix.identity();
|
||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||
modelTransformMatrix.scale(new Vector3d(aabb.maxX - aabb.minX,aabb.maxY - aabb.minY,aabb.maxZ - aabb.minZ));
|
||||
model.setModelMatrix(modelTransformMatrix);
|
||||
model.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an area select
|
||||
* @param openGLState The opengl state
|
||||
* @param renderPipelineState The render pipeline state
|
||||
* @param modelTransformMatrix The model transform matrix
|
||||
* @param areaSelection The area selection
|
||||
*/
|
||||
static void renderTube(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, double radius, String texturePath){
|
||||
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER);
|
||||
if(model != null){
|
||||
Texture texture = Globals.assetManager.fetchTexture(texturePath);
|
||||
if(texture != null){
|
||||
texture.bind(openGLState);
|
||||
}
|
||||
//calculate camera-modified vector3d
|
||||
Vector3d cameraModifiedPosition = new Vector3d(end).lerp(new Vector3d(start),0.5).sub(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
|
||||
modelTransformMatrix.identity();
|
||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||
modelTransformMatrix.rotate(SpatialMathUtils.calculateRotationFromPointToPoint(start, end).mul(new Quaterniond().rotateZ(Math.PI / 2.0)));
|
||||
modelTransformMatrix.scale(new Vector3d(radius,end.distance(start) / 2.0,radius));
|
||||
model.setModelMatrix(modelTransformMatrix);
|
||||
model.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bone debugging pipeline
|
||||
* @return The bone debugging pipeline
|
||||
|
||||
@ -18,6 +18,7 @@ import electrosphere.server.macro.spatial.MacroObject;
|
||||
import electrosphere.server.macro.structure.VirtualStructure;
|
||||
import electrosphere.server.macro.town.Town;
|
||||
import electrosphere.util.FileUtils;
|
||||
import electrosphere.util.math.GeomUtils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -310,14 +311,20 @@ public class MacroData {
|
||||
* @return true if it intersects any existing structs, false otheriwse
|
||||
*/
|
||||
public boolean intersectsStruct(AABBd aabb){
|
||||
List<MacroAreaObject> areaObjs = new LinkedList<MacroAreaObject>();
|
||||
areaObjs.addAll(this.roads);
|
||||
areaObjs.addAll(this.structures);
|
||||
for(MacroAreaObject areaObj : areaObjs){
|
||||
if(areaObj.getAABB().testAABB(aabb)){
|
||||
for(VirtualStructure struct : this.structures){
|
||||
if(struct.getAABB().testAABB(aabb)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(Road road : this.roads){
|
||||
//broad phase
|
||||
if(road.getAABB().testAABB(aabb)){
|
||||
//near phase
|
||||
if(GeomUtils.intersectAABBTube(aabb, road.getPoint1(), road.getPoint2(), road.getRadius())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -90,23 +90,17 @@ public class TownLayout {
|
||||
|
||||
//
|
||||
//generate roads
|
||||
Road newRoad;
|
||||
Road upRoad = Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
|
||||
Road rightRoad = Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
|
||||
Road leftRoad = Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
|
||||
Road downRoad = Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
|
||||
|
||||
//up-facing road
|
||||
newRoad = Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
|
||||
|
||||
//right-facing road
|
||||
newRoad = Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
|
||||
|
||||
//left-facing road
|
||||
newRoad = Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
|
||||
|
||||
//down-facing road
|
||||
newRoad = Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
|
||||
//
|
||||
//place structures along roads
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, upRoad, allowedStructures);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, rightRoad, allowedStructures);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, leftRoad, allowedStructures);
|
||||
TownLayout.generateStructuresAlongRoad(realm, town, downRoad, allowedStructures);
|
||||
|
||||
town.setResolution(Town.TOWN_RES_MAX);
|
||||
}
|
||||
@ -135,12 +129,14 @@ public class TownLayout {
|
||||
isNorthSouth = true;
|
||||
}
|
||||
|
||||
int roadRadiusOffsetRaw = (int)(road.getRadius() + 3);
|
||||
|
||||
//offset applied to the scan location to not place it on top of the road
|
||||
Vector3d placementOffset = null;
|
||||
Vector3d roadOffset = null;
|
||||
if(isNorthSouth){
|
||||
placementOffset = new Vector3d(road.getRadius() + 10,0,0);
|
||||
roadOffset = new Vector3d(roadRadiusOffsetRaw,0,0);
|
||||
} else {
|
||||
placementOffset = new Vector3d(0,0,road.getRadius() + 10);
|
||||
roadOffset = new Vector3d(0,0,roadRadiusOffsetRaw);
|
||||
}
|
||||
|
||||
//the position to try at
|
||||
@ -151,9 +147,10 @@ public class TownLayout {
|
||||
StructureData structureData = allowedStructures.get(0);
|
||||
|
||||
//scan along the length of the road
|
||||
for(int i = 0; i < len; i++){
|
||||
for(int i = roadRadiusOffsetRaw; i < len; i++){
|
||||
//solve terrain position to place
|
||||
currPos.set(dir).mul(i).add(startPoint).add(placementOffset);
|
||||
currPos.set(startPoint).lerp(endPoint,i/(double)len).add(roadOffset);
|
||||
// currPos.set(dir).mul(i).add(startPoint).add(roadOffset);
|
||||
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
||||
//apply structure placement offset
|
||||
currPos.add(structureData.getPlacementOffset());
|
||||
@ -170,7 +167,7 @@ public class TownLayout {
|
||||
//scan along the length of the road
|
||||
for(int i = 0; i < len; i++){
|
||||
//solve terrain position to place
|
||||
currPos.set(dir).mul(i).add(startPoint).sub(placementOffset).sub(structureData.getDimensions().x,0,structureData.getDimensions().z);
|
||||
currPos.set(dir).mul(i).add(startPoint).sub(roadOffset).sub(structureData.getDimensions().x,0,structureData.getDimensions().z);
|
||||
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
||||
//apply structure placement offset
|
||||
currPos.add(structureData.getPlacementOffset());
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package electrosphere.util.math;
|
||||
|
||||
import org.joml.AABBd;
|
||||
import org.joml.Intersectiond;
|
||||
import org.joml.Vector2d;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
@ -663,5 +665,28 @@ public class GeomUtils {
|
||||
double dist = Intersectiond.distancePointLine(point.x, point.y, point.z, lineStart.x, lineStart.y, lineStart.z, lineEnd.x, lineEnd.y, lineEnd.z);
|
||||
return dist < radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an aabb intersects a tube
|
||||
* @param aabb The aabb
|
||||
* @param tubeStart The start of the tube
|
||||
* @param tubeEnd The end of the tube
|
||||
* @param radius The radius of the tube
|
||||
* @return true if they intersect, false
|
||||
*/
|
||||
public static boolean intersectAABBTube(AABBd aabb, Vector3d tubeStart, Vector3d tubeEnd, double radius){
|
||||
Vector2d resDat = new Vector2d();
|
||||
int res = Intersectiond.intersectLineSegmentAab(
|
||||
tubeStart.x, tubeStart.y, tubeStart.z,
|
||||
tubeEnd.x, tubeEnd.y, tubeEnd.z,
|
||||
aabb.minX - radius, aabb.minY - radius, aabb.minZ - radius,
|
||||
aabb.maxX + radius, aabb.maxY + radius, aabb.maxZ + radius,
|
||||
resDat
|
||||
);
|
||||
if(res != Intersectiond.OUTSIDE){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user