async load texture atlas
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
cfbd4c05ce
commit
ac12b3f5a8
@ -259,6 +259,12 @@ Ground Texture Atlas system
|
|||||||
- Basic atlas working with marching cubes
|
- Basic atlas working with marching cubes
|
||||||
- Make it work with triplanar mapping
|
- Make it work with triplanar mapping
|
||||||
|
|
||||||
|
(05/05/2024)
|
||||||
|
Synchronize attack tree over network
|
||||||
|
|
||||||
|
Clean up data
|
||||||
|
- Tree Model Paths
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|||||||
@ -3,20 +3,7 @@ package electrosphere.client.terrain.cells;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.joml.Vector2i;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.game.data.voxel.VoxelData;
|
|
||||||
import electrosphere.game.data.voxel.VoxelType;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
|
||||||
import electrosphere.renderer.texture.Texture;
|
import electrosphere.renderer.texture.Texture;
|
||||||
import electrosphere.util.FileUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An atlas texture and accompanying map of all voxel textures
|
* An atlas texture and accompanying map of all voxel textures
|
||||||
@ -41,37 +28,28 @@ public class VoxelTextureAtlas {
|
|||||||
public static final int ELEMENTS_PER_ROW = ATLAS_DIM / ATLAS_ELEMENT_DIM;
|
public static final int ELEMENTS_PER_ROW = ATLAS_DIM / ATLAS_ELEMENT_DIM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the voxel texture atlas object
|
* Puts an entry in the type-coord map to map a voxel type to a position
|
||||||
* @return the atlas object
|
* @param type the voxel type
|
||||||
|
* @param coord the coordinate in the map
|
||||||
*/
|
*/
|
||||||
public static VoxelTextureAtlas createVoxelTextureAtlas(VoxelData data){
|
public void putTypeCoord(int type, int coord){
|
||||||
Globals.profiler.beginCpuSample("createVoxelTextureAtlas");
|
typeCoordMap.put(type,coord);
|
||||||
VoxelTextureAtlas rVal = new VoxelTextureAtlas();
|
|
||||||
int iterator = 0;
|
|
||||||
BufferedImage image = new BufferedImage(ATLAS_DIM, ATLAS_DIM, BufferedImage.TYPE_4BYTE_ABGR);
|
|
||||||
Graphics graphics = image.getGraphics();
|
|
||||||
for(VoxelType type : data.getTypes()){
|
|
||||||
if(type.getTexture() != null){
|
|
||||||
int offX = iterator % ELEMENTS_PER_ROW;
|
|
||||||
int offY = iterator / ELEMENTS_PER_ROW;
|
|
||||||
try {
|
|
||||||
BufferedImage newType = ImageIO.read(FileUtils.getAssetFile(type.getTexture()));
|
|
||||||
graphics.drawImage(newType, iterator * ATLAS_ELEMENT_DIM * offX, ATLAS_DIM - ATLAS_ELEMENT_DIM - iterator * ATLAS_ELEMENT_DIM * offY, null);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LoggerInterface.loggerRenderer.ERROR("Texture atlas failed to find texture " + type.getTexture(), e);
|
|
||||||
}
|
}
|
||||||
//put coords in map
|
|
||||||
rVal.typeCoordMap.put(type.getId(),iterator);
|
|
||||||
|
|
||||||
//iterate
|
/**
|
||||||
iterator++;
|
* Sets the specular
|
||||||
|
* @param specular the specular
|
||||||
|
*/
|
||||||
|
public void setSpecular(Texture specular){
|
||||||
|
this.specular = specular;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Globals.profiler.endCpuSample();
|
/**
|
||||||
//construct texture atlas from buffered image
|
* Sets the normal
|
||||||
rVal.specular = new Texture(image);
|
* @param normal the normal
|
||||||
rVal.normal = new Texture(image);
|
*/
|
||||||
return rVal;
|
public void setNormal(Texture normal){
|
||||||
|
this.normal = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import electrosphere.controls.MouseCallback;
|
|||||||
import electrosphere.controls.ScrollCallback;
|
import electrosphere.controls.ScrollCallback;
|
||||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||||
import electrosphere.engine.assetmanager.AssetManager;
|
import electrosphere.engine.assetmanager.AssetManager;
|
||||||
|
import electrosphere.engine.loadingthreads.InitialAssetLoading;
|
||||||
import electrosphere.engine.loadingthreads.LoadingThread;
|
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||||
import electrosphere.engine.profiler.Profiler;
|
import electrosphere.engine.profiler.Profiler;
|
||||||
import electrosphere.engine.time.Timekeeper;
|
import electrosphere.engine.time.Timekeeper;
|
||||||
@ -58,7 +59,6 @@ import electrosphere.renderer.light.PointLight;
|
|||||||
import electrosphere.renderer.light.SpotLight;
|
import electrosphere.renderer.light.SpotLight;
|
||||||
import electrosphere.renderer.loading.ModelPretransforms;
|
import electrosphere.renderer.loading.ModelPretransforms;
|
||||||
import electrosphere.renderer.meshgen.FluidChunkModelGeneration;
|
import electrosphere.renderer.meshgen.FluidChunkModelGeneration;
|
||||||
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
|
||||||
import electrosphere.renderer.model.Material;
|
import electrosphere.renderer.model.Material;
|
||||||
import electrosphere.renderer.shader.ShaderOptionMap;
|
import electrosphere.renderer.shader.ShaderOptionMap;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.shader.ShaderProgram;
|
||||||
@ -333,7 +333,7 @@ public class Globals {
|
|||||||
//chunk stuff
|
//chunk stuff
|
||||||
//draw cell manager
|
//draw cell manager
|
||||||
public static DrawCellManager drawCellManager;
|
public static DrawCellManager drawCellManager;
|
||||||
public static VoxelTextureAtlas voxelTextureAtlas;
|
public static VoxelTextureAtlas voxelTextureAtlas = new VoxelTextureAtlas();
|
||||||
|
|
||||||
//fluid cell manager
|
//fluid cell manager
|
||||||
public static FluidCellManager fluidCellManager;
|
public static FluidCellManager fluidCellManager;
|
||||||
@ -348,6 +348,7 @@ public class Globals {
|
|||||||
|
|
||||||
//thread for loading different game states
|
//thread for loading different game states
|
||||||
public static List<LoadingThread> loadingThreadsList = new LinkedList<LoadingThread>();
|
public static List<LoadingThread> loadingThreadsList = new LinkedList<LoadingThread>();
|
||||||
|
public static InitialAssetLoading initialAssetLoadingThread = new InitialAssetLoading();
|
||||||
|
|
||||||
//manager for all widgets currently being drawn to screen
|
//manager for all widgets currently being drawn to screen
|
||||||
public static ElementManager elementManager;
|
public static ElementManager elementManager;
|
||||||
@ -551,9 +552,6 @@ public class Globals {
|
|||||||
assetManager.addShaderToQueue("Shaders/ui/debug/windowBorder/windowBound.vs", null, "Shaders/ui/debug/windowBorder/windowBound.fs");
|
assetManager.addShaderToQueue("Shaders/ui/debug/windowBorder/windowBound.vs", null, "Shaders/ui/debug/windowBorder/windowBound.fs");
|
||||||
assetManager.addShaderToQueue("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", null, "Shaders/ui/debug/windowContentBorder/windowContentBound.fs");
|
assetManager.addShaderToQueue("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", null, "Shaders/ui/debug/windowContentBorder/windowContentBound.fs");
|
||||||
|
|
||||||
//voxel texture atlas
|
|
||||||
voxelTextureAtlas = VoxelTextureAtlas.createVoxelTextureAtlas(Globals.gameConfigCurrent.getVoxelData());
|
|
||||||
|
|
||||||
//as these assets are required for the renderer to work, we go ahead and
|
//as these assets are required for the renderer to work, we go ahead and
|
||||||
//load them into memory now. The loading time penalty is worth it I think.
|
//load them into memory now. The loading time penalty is worth it I think.
|
||||||
Globals.assetManager.loadAssetsInQueue();
|
Globals.assetManager.loadAssetsInQueue();
|
||||||
|
|||||||
@ -134,10 +134,14 @@ public class Main {
|
|||||||
|
|
||||||
//create the drawing context
|
//create the drawing context
|
||||||
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
|
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
|
||||||
|
//create opengl context
|
||||||
Globals.renderingEngine = new RenderingEngine();
|
Globals.renderingEngine = new RenderingEngine();
|
||||||
Globals.renderingEngine.createOpenglContext();
|
Globals.renderingEngine.createOpenglContext();
|
||||||
Globals.initDefaultGraphicalResources();
|
Globals.initDefaultGraphicalResources();
|
||||||
ImGuiWindowMacros.initImGuiWindows();
|
ImGuiWindowMacros.initImGuiWindows();
|
||||||
|
|
||||||
|
//start initial asset loading
|
||||||
|
new Thread(Globals.initialAssetLoadingThread).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
|||||||
@ -3,8 +3,8 @@ package electrosphere.engine.assetmanager;
|
|||||||
import electrosphere.audio.AudioBuffer;
|
import electrosphere.audio.AudioBuffer;
|
||||||
import electrosphere.collision.CollisionBodyCreation;
|
import electrosphere.collision.CollisionBodyCreation;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.engine.assetmanager.queue.QueuedAsset;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.actor.ActorShaderMask;
|
import electrosphere.renderer.actor.ActorShaderMask;
|
||||||
import electrosphere.renderer.buffer.HomogenousInstancedArray;
|
import electrosphere.renderer.buffer.HomogenousInstancedArray;
|
||||||
@ -22,10 +22,10 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
import org.lwjgl.assimp.AIScene;
|
import org.lwjgl.assimp.AIScene;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
import org.ode4j.ode.DWorld;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages all assets loaded into the engine including initially loading and destructing
|
* Manages all assets loaded into the engine including initially loading and destructing
|
||||||
@ -58,6 +58,11 @@ public class AssetManager {
|
|||||||
List<HomogenousInstancedArray> instanceArrayBufferAllocationQueue = new CopyOnWriteArrayList<HomogenousInstancedArray>();
|
List<HomogenousInstancedArray> instanceArrayBufferAllocationQueue = new CopyOnWriteArrayList<HomogenousInstancedArray>();
|
||||||
|
|
||||||
|
|
||||||
|
//assets queued to be loaded
|
||||||
|
Semaphore queuedAssetLock = new Semaphore(1);
|
||||||
|
List<QueuedAsset> queuedAssets = new CopyOnWriteArrayList<QueuedAsset>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -116,6 +121,13 @@ public class AssetManager {
|
|||||||
AIScene scene = ModelLoader.loadAIScene(currentPath);
|
AIScene scene = ModelLoader.loadAIScene(currentPath);
|
||||||
poseModelsLoadedIntoMemory.put(currentPath, new PoseModel(currentPath, scene));
|
poseModelsLoadedIntoMemory.put(currentPath, new PoseModel(currentPath, scene));
|
||||||
}
|
}
|
||||||
|
//queued assets
|
||||||
|
queuedAssetLock.acquireUninterruptibly();
|
||||||
|
for(QueuedAsset queuedAsset : queuedAssets){
|
||||||
|
queuedAsset.load();
|
||||||
|
}
|
||||||
|
queuedAssets.clear();
|
||||||
|
queuedAssetLock.release();
|
||||||
//allocate homogenous buffers
|
//allocate homogenous buffers
|
||||||
allocateHomogenousBuffers();
|
allocateHomogenousBuffers();
|
||||||
//allocate instance array buffers
|
//allocate instance array buffers
|
||||||
@ -430,5 +442,19 @@ public class AssetManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//Async generic queued assets
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Queues an asset to be loaded on the main thread
|
||||||
|
* @param asset the asset
|
||||||
|
*/
|
||||||
|
public void queuedAsset(QueuedAsset asset){
|
||||||
|
queuedAssetLock.acquireUninterruptibly();
|
||||||
|
this.queuedAssets.add(asset);
|
||||||
|
queuedAssetLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package electrosphere.engine.assetmanager.queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An asset that has its data ready to be buffered to gpu
|
||||||
|
*/
|
||||||
|
public interface QueuedAsset {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the asset
|
||||||
|
*/
|
||||||
|
public void load();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the queued asset has been loaded or not
|
||||||
|
* @return True if it has been loaded to gpu/wherever, false otherise
|
||||||
|
*/
|
||||||
|
public boolean hasLoaded();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package electrosphere.engine.assetmanager.queue;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
import electrosphere.renderer.texture.Texture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A texture queued to be sent to the gpu
|
||||||
|
*/
|
||||||
|
public class QueuedTexture implements QueuedAsset {
|
||||||
|
|
||||||
|
//true if loaded
|
||||||
|
boolean hasLoaded = false;
|
||||||
|
|
||||||
|
//the resulting texture object
|
||||||
|
Texture texture = null;
|
||||||
|
|
||||||
|
//data to be loaded
|
||||||
|
BufferedImage data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the queued texture object
|
||||||
|
* @param image the image to load to gpu
|
||||||
|
*/
|
||||||
|
public QueuedTexture(BufferedImage image){
|
||||||
|
this.data = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
texture = new Texture(data);
|
||||||
|
hasLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasLoaded() {
|
||||||
|
return hasLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the texture object
|
||||||
|
* @return The texture if it has been loaded, otherwise null
|
||||||
|
*/
|
||||||
|
public Texture getTexture(){
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -232,7 +232,7 @@ public class ClientLoading {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void initDrawCellManager(){
|
static void initDrawCellManager(){
|
||||||
while(Globals.clientWorldData == null){
|
while(Globals.clientWorldData == null || Globals.initialAssetLoadingThread.isLoading()){
|
||||||
try {
|
try {
|
||||||
TimeUnit.MILLISECONDS.sleep(10);
|
TimeUnit.MILLISECONDS.sleep(10);
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
|
|||||||
@ -0,0 +1,104 @@
|
|||||||
|
package electrosphere.engine.loadingthreads;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.engine.assetmanager.queue.QueuedTexture;
|
||||||
|
import electrosphere.game.data.voxel.VoxelData;
|
||||||
|
import electrosphere.game.data.voxel.VoxelType;
|
||||||
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The intention of this thread is to load basic assets that the engine should generally have available from the start.
|
||||||
|
* Examples:
|
||||||
|
* - Texture Atlas for terrain
|
||||||
|
* - Icons for items
|
||||||
|
*/
|
||||||
|
public class InitialAssetLoading implements Runnable {
|
||||||
|
|
||||||
|
//tracks whether this thread is still doing work or not
|
||||||
|
boolean loading = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads basic data
|
||||||
|
*/
|
||||||
|
public void LoadData(){
|
||||||
|
|
||||||
|
|
||||||
|
loadTextureAtlas();
|
||||||
|
LoggerInterface.loggerEngine.INFO("Finished loading texture atlas");
|
||||||
|
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the thread is still loading or not
|
||||||
|
* @return true if loading, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isLoading(){
|
||||||
|
return loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the texture atlas
|
||||||
|
*/
|
||||||
|
private void loadTextureAtlas(){
|
||||||
|
//terrain texture atlas
|
||||||
|
Globals.profiler.beginCpuSample("createVoxelTextureAtlas");
|
||||||
|
VoxelData data = Globals.gameConfigCurrent.getVoxelData();
|
||||||
|
int iterator = 0;
|
||||||
|
BufferedImage image = new BufferedImage(VoxelTextureAtlas.ATLAS_DIM, VoxelTextureAtlas.ATLAS_DIM, BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
Graphics graphics = image.getGraphics();
|
||||||
|
for(VoxelType type : data.getTypes()){
|
||||||
|
if(type.getTexture() != null){
|
||||||
|
int offX = iterator % VoxelTextureAtlas.ELEMENTS_PER_ROW;
|
||||||
|
int offY = iterator / VoxelTextureAtlas.ELEMENTS_PER_ROW;
|
||||||
|
try {
|
||||||
|
BufferedImage newType = ImageIO.read(FileUtils.getAssetFile(type.getTexture()));
|
||||||
|
graphics.drawImage(newType, iterator * VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offX, VoxelTextureAtlas.ATLAS_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM - iterator * VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offY, null);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LoggerInterface.loggerRenderer.ERROR("Texture atlas failed to find texture " + type.getTexture(), e);
|
||||||
|
}
|
||||||
|
//put coords in map
|
||||||
|
Globals.voxelTextureAtlas.putTypeCoord(type.getId(),iterator);
|
||||||
|
|
||||||
|
//iterate
|
||||||
|
iterator++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
//queue to asset manager
|
||||||
|
QueuedTexture atlasQueuedTexture = new QueuedTexture(image);
|
||||||
|
Globals.assetManager.queuedAsset(atlasQueuedTexture);
|
||||||
|
|
||||||
|
|
||||||
|
//wait the texture to be loaded
|
||||||
|
while(!atlasQueuedTexture.hasLoaded()){
|
||||||
|
try {
|
||||||
|
TimeUnit.MILLISECONDS.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LoggerInterface.loggerEngine.ERROR("failed to sleep", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//construct texture atlas from buffered image
|
||||||
|
Globals.voxelTextureAtlas.setSpecular(atlasQueuedTexture.getTexture());
|
||||||
|
Globals.voxelTextureAtlas.setNormal(atlasQueuedTexture.getTexture());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
this.LoadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -91,4 +91,14 @@ public class ServerEntityUtils {
|
|||||||
EntityUtils.cleanUpEntity(entity);
|
EntityUtils.cleanUpEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guarantees that the returned position is in bounds of the server realm
|
||||||
|
* @param realm The realm to test
|
||||||
|
* @param position the position
|
||||||
|
* @return Either the position if it is in bounds, or the closest position that is in bounds
|
||||||
|
*/
|
||||||
|
public static Vector3d guaranteePositionIsInBounds(Realm realm, Vector3d position){
|
||||||
|
return realm.getDataCellManager().guaranteePositionIsInBounds(position);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -325,7 +325,7 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
||||||
state = AttackTreeState.IDLE;
|
state = AttackTreeState.IDLE;
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
||||||
@ -374,6 +374,7 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
} else if(state != AttackTreeState.IDLE){
|
} else if(state != AttackTreeState.IDLE){
|
||||||
//checks if we have a next move and if we're in the specified range of frames when we're allowed to chain into it
|
//checks if we have a next move and if we're in the specified range of frames when we're allowed to chain into it
|
||||||
if(
|
if(
|
||||||
|
currentMove != null &&
|
||||||
currentMove.getNextMoveId() != null &&
|
currentMove.getNextMoveId() != null &&
|
||||||
!currentMove.getNextMoveId().equals("") &&
|
!currentMove.getNextMoveId().equals("") &&
|
||||||
frameCurrent >= currentMove.getMoveChainWindowStart() && frameCurrent <= currentMove.getMoveChainWindowEnd()
|
frameCurrent >= currentMove.getMoveChainWindowStart() && frameCurrent <= currentMove.getMoveChainWindowEnd()
|
||||||
|
|||||||
@ -121,9 +121,18 @@ public class ItemUtils {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns an item on the server
|
||||||
|
* @param realm the realm to spawn in
|
||||||
|
* @param position the position to spawn at
|
||||||
|
* @param name the name of the item to spawn
|
||||||
|
* @return The item entity
|
||||||
|
*/
|
||||||
public static Entity serverSpawnBasicItem(Realm realm, Vector3d position, String name){
|
public static Entity serverSpawnBasicItem(Realm realm, Vector3d position, String name){
|
||||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
|
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);// EntityUtils.spawnDrawableEntity(item.getModelPath());
|
//must correct the position such that it spawns inside the realm
|
||||||
|
Vector3d correctedPosition = ServerEntityUtils.guaranteePositionIsInBounds(realm, position);
|
||||||
|
Entity rVal = EntityCreationUtils.createServerEntity(realm, correctedPosition);// EntityUtils.spawnDrawableEntity(item.getModelPath());
|
||||||
EntityCreationUtils.makeEntityPoseable(rVal, item.getModelPath());
|
EntityCreationUtils.makeEntityPoseable(rVal, item.getModelPath());
|
||||||
if(item.getWeaponData() != null){
|
if(item.getWeaponData() != null){
|
||||||
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
@ -194,7 +203,7 @@ public class ItemUtils {
|
|||||||
//Burried underneath this is function call to initialize a server side entity.
|
//Burried underneath this is function call to initialize a server side entity.
|
||||||
//The server initialization logic checks what type of entity this is, if this function is called prior to its type being stored
|
//The server initialization logic checks what type of entity this is, if this function is called prior to its type being stored
|
||||||
//the server will not be able to synchronize it properly.
|
//the server will not be able to synchronize it properly.
|
||||||
ServerEntityUtils.initiallyPositionEntity(realm,rVal,position);
|
ServerEntityUtils.initiallyPositionEntity(realm,rVal,correctedPosition);
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -524,4 +524,28 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3d guaranteePositionIsInBounds(Vector3d positionToTest) {
|
||||||
|
Vector3d returnPos = new Vector3d(positionToTest);
|
||||||
|
if(positionToTest.x < 0){
|
||||||
|
returnPos.x = 0;
|
||||||
|
}
|
||||||
|
if(positionToTest.x >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
|
||||||
|
returnPos.x = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
|
||||||
|
}
|
||||||
|
if(positionToTest.y < 0){
|
||||||
|
returnPos.y = 0;
|
||||||
|
}
|
||||||
|
if(positionToTest.y >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
|
||||||
|
returnPos.y = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
|
||||||
|
}
|
||||||
|
if(positionToTest.z < 0){
|
||||||
|
returnPos.z = 0;
|
||||||
|
}
|
||||||
|
if(positionToTest.z >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
|
||||||
|
returnPos.z = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
|
||||||
|
}
|
||||||
|
return returnPos;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,4 +77,11 @@ public interface DataCellManager {
|
|||||||
*/
|
*/
|
||||||
public void save(String saveName);
|
public void save(String saveName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guarantees that the returned position is in bounds
|
||||||
|
* @param positionToTest the position
|
||||||
|
* @return Either the position if it is in bounds, or the closest position that is in bounds
|
||||||
|
*/
|
||||||
|
public Vector3d guaranteePositionIsInBounds(Vector3d positionToTest);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user