particle work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-08-18 18:27:23 -04:00
parent 0905157327
commit af4d1317fc
24 changed files with 497 additions and 125 deletions

View File

@ -0,0 +1,13 @@
{
"data" : [
{
"name" : "blood",
"maxLife" : 7,
"lifeCurrent" : 0,
"velocity" : 0.3,
"acceleration" : -0.1,
"size": 0.15,
"texture" : "Textures/bloodsplat1.png"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -20,6 +20,7 @@
+ bug fixes
Fix anime outlines drawing over solid geometry
Fix anime outlines not drawing for first person pipeline
Fix falling tree not always deactivating on server
Fix AI tracking deleted entity
Fix server ground movement tree playing animation over falling animation
Fix empty item slot not showing underneath dragged item

View File

@ -63,7 +63,10 @@
"receiverEntityID",
"time",
"hitboxType",
"hurtboxType"
"hurtboxType",
"positionX",
"positionY",
"positionZ"
]
}

View File

@ -2,8 +2,12 @@ package electrosphere.client.collision;
import org.joml.Vector3d;
import electrosphere.client.effects.ParticleEffects;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.game.data.collidable.HitboxData;
import electrosphere.logger.LoggerInterface;
@ -26,9 +30,11 @@ public class ClientHitboxCollision {
case HitboxData.HITBOX_TYPE_HURT:
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
ClientHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
} break;
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
ClientHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
} break;
default: {
LoggerInterface.loggerEngine.WARNING("Client handling undefined hurtbox type: " + hurtboxType);
@ -41,4 +47,80 @@ public class ClientHitboxCollision {
}
}
/**
* Figures out what particles to spawn based on a collisionn
* @param senderEntity The entity initiating the collision
* @param receiverEntity The entity receiving the collision
* @param hitboxType The hitbox type
* @param hurtboxType The hurtbox type
* @param position The position of the collision
*/
private static void conditionallySpawnParticles(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType, Vector3d position){
boolean isBlockSound = false;
boolean isDamageSound = false;
switch(hitboxType){
case HitboxData.HITBOX_TYPE_HIT:
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
switch(hurtboxType){
case HitboxData.HITBOX_TYPE_HIT:
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
isBlockSound = true;
} break;
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
isBlockSound = true;
} break;
case HitboxData.HITBOX_TYPE_HURT:
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
isDamageSound = true;
} break;
}
} break;
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
switch(hurtboxType){
case HitboxData.HITBOX_TYPE_HIT:
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
isBlockSound = true;
} break;
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
isBlockSound = true;
} break;
case HitboxData.HITBOX_TYPE_HURT:
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
} break;
}
} break;
case HitboxData.HITBOX_TYPE_HURT:
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
} break;
}
if(ItemUtils.isWeapon(senderEntity)){
if(CreatureUtils.isCreature(receiverEntity)){
if(isBlockSound){
//TODO: handle
} else if(isDamageSound){
ParticleEffects.spawnBloodsplats(position);
}
} else if(ItemUtils.isWeapon(receiverEntity)){
if(isBlockSound){
//TODO: handle
}
} else {
String message = "Getting audio for unhandled hurtbox collision type!\n" +
"Is creature: " + CreatureUtils.isCreature(receiverEntity) + "\n" +
"Is item: " + ItemUtils.isItem(receiverEntity) + "\n" +
"Is weapon: " + ItemUtils.isWeapon(receiverEntity) + "\n" +
"Is object: " + ObjectUtils.isObject(receiverEntity);
if(ItemUtils.isItem(receiverEntity)){
message = message + "\nItem Type: " + ItemUtils.getType(receiverEntity);
}
LoggerInterface.loggerEngine.WARNING(message);
}
} else {
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hitbox collision type!");
}
}
}

View File

@ -0,0 +1,47 @@
package electrosphere.client.effects;
import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.particle.ParticleUtils;
import electrosphere.game.data.particle.ParticleData;
import java.util.Random;
import org.joml.Quaterniond;
import org.joml.Vector3d;
/**
* Utility functions for spawning particle effects
*/
public class ParticleEffects {
/**
* Spawns bloodsplats based on a collision
* @param position The position of the collision
*/
public static void spawnBloodsplats(Vector3d position){
int max = 30;
int min = 10;
ParticleData bloodsplatData = null;
for(ParticleData data : Globals.gameConfigCurrent.getParticleDefinition().getData()){
if(data.getName().equals("blood")){
bloodsplatData = data;
}
}
Random rand = new Random();
int num = (int)(rand.nextFloat() * (max - min)) + min;
for(int i = 0; i < num; i++){
Vector3d destination = new Vector3d(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize();
Entity particleEntity = ParticleUtils.clientSpawnBillboardParticle(bloodsplatData, destination);
ClientEntityUtils.initiallyPositionEntity(
particleEntity,
position,
new Quaterniond()
);
EntityUtils.getScale(particleEntity).mul(bloodsplatData.getSize());
}
}
}

View File

@ -16,7 +16,6 @@ import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.particle.ParticleUtils;
import electrosphere.renderer.actor.Actor;
public class ClientSimulation {
@ -75,12 +74,6 @@ public class ClientSimulation {
}
Globals.profiler.endCpuSample();
//
//particle state updates
Globals.profiler.beginCpuSample("particle state updates");
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
ParticleUtils.makeParticleBillboardFaceCamera(particle);
}
Globals.profiler.endCpuSample();
//update attached entity positions
AttachUtils.clientUpdateAttachedEntityPositions();
//

View File

@ -38,6 +38,7 @@ import electrosphere.engine.time.Timekeeper;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.game.config.UserSettings;
import electrosphere.game.data.particle.ParticleDefinition;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.game.server.structure.virtual.StructureManager;
import electrosphere.game.server.world.MacroData;
@ -266,7 +267,11 @@ public class Globals {
public static ShaderProgram defaultMeshShader;
public static ShaderProgram terrainShaderProgram;
//
// Particle stuff
//
public static String particleBillboardModel;
public static ParticleDefinition particleDefinition;
public static ShaderOptionMap shaderOptionMap;
@ -515,6 +520,7 @@ public class Globals {
"Textures/color/transparent_orange.png",
"Textures/color/transparent_teal.png",
"Textures/color/transparent_yellow.png",
"Textures/bloodsplat1.png",
};
/**

View File

@ -141,7 +141,10 @@ public class ServerLifeTree implements BehaviorTree {
parent.getId(),
Globals.timekeeper.getNumberOfSimFramesElapsed(),
event.sourceHitboxData.getHitboxData().getType(),
HitboxData.HITBOX_TYPE_BLOCK_CONNECTED
HitboxData.HITBOX_TYPE_BLOCK_CONNECTED,
event.position.x,
event.position.y,
event.position.z
)
);
}
@ -161,7 +164,10 @@ public class ServerLifeTree implements BehaviorTree {
parent.getId(),
Globals.timekeeper.getNumberOfSimFramesElapsed(),
event.sourceHitboxData.getHitboxData().getType(),
event.parentHitboxData.getHitboxData().getType()
event.parentHitboxData.getHitboxData().getType(),
event.position.x,
event.position.y,
event.position.z
)
);
@ -189,7 +195,7 @@ public class ServerLifeTree implements BehaviorTree {
* @param isBlock True if this is a block event
*/
public void addCollisionEvent(Entity collisionSource, HitboxState sourceHitboxData, HitboxState parentHitboxData, Vector3d position, boolean isDamage, boolean isBlock){
CollisionEvent collisionEvent = new CollisionEvent(collisionSource, sourceHitboxData, parentHitboxData, isDamage, isBlock);
CollisionEvent collisionEvent = new CollisionEvent(collisionSource, sourceHitboxData, parentHitboxData, isDamage, isBlock, position);
this.collisionAccumulator.add(collisionEvent);
}
@ -314,6 +320,11 @@ public class ServerLifeTree implements BehaviorTree {
*/
boolean isBlock;
/**
* The position of the collision
*/
Vector3d position;
/**
* Constructor
* @param source The source of the collision
@ -321,13 +332,15 @@ public class ServerLifeTree implements BehaviorTree {
* @param parentHitboxData The hitbox data for the parent of the tree
* @param isDamage True if this is a damage event
* @param isBlock True if this is a block event
* @param position The position of the collision
*/
public CollisionEvent(Entity source, HitboxState sourceHitboxData, HitboxState parentHitboxData, boolean isDamage, boolean isBlock){
public CollisionEvent(Entity source, HitboxState sourceHitboxData, HitboxState parentHitboxData, boolean isDamage, boolean isBlock, Vector3d position){
this.source = source;
this.sourceHitboxData = sourceHitboxData;
this.parentHitboxData = parentHitboxData;
this.isDamage = isDamage;
this.isBlock = isBlock;
this.position = position;
}
}

View File

@ -1,13 +1,17 @@
package electrosphere.entity.state.particle;
import org.joml.AxisAngle4f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.game.data.particle.ParticleData;
/**
* Particle component for a client-side particle
@ -26,7 +30,7 @@ public class ClientParticleTree implements BehaviorTree {
//The destination of the particle
Vector3f destination;
Vector3d destination;
//the velocity of the particle
float velocity;
@ -35,15 +39,29 @@ public class ClientParticleTree implements BehaviorTree {
float acceleration;
/**
* Constructor
* @param parent
* @param params
*/
private ClientParticleTree(Entity parent, Object ... params){
//int maxLife, Vector3f destination, float velocity, float acceleration, boolean hasLife
if(params.length < 1){
throw new IllegalArgumentException("No particle data was provided");
}
if(params.length < 2){
throw new IllegalArgumentException("No destination set for the particle");
}
ParticleData particleData = (ParticleData)params[0];
Vector3d destination = (Vector3d)params[1];
//sets data for the tree
this.parent = parent;
this.maxLife = maxLife;
this.maxLife = particleData.getMaxLife();
this.destination = destination;
this.velocity = velocity;
this.acceleration = acceleration;
this.hasLife = hasLife;
lifeCurrent = maxLife;
this.velocity = particleData.getVelocity();
this.acceleration = particleData.getAcceleration();
this.hasLife = particleData.getMaxLife() != null;
this.lifeCurrent = maxLife;
}
public int getMaxLife() {
@ -54,7 +72,7 @@ public class ClientParticleTree implements BehaviorTree {
return lifeCurrent;
}
public Vector3f getDestination() {
public Vector3d getDestination() {
return destination;
}
@ -69,8 +87,8 @@ public class ClientParticleTree implements BehaviorTree {
@Override
public void simulate(float deltaTime){
Vector3d parentPosition = EntityUtils.getPosition(parent);
parentPosition.add(new Vector3f(destination).mul(velocity));
velocity = velocity - acceleration;
parentPosition.add(new Vector3d(destination).mul(velocity));
velocity = velocity + acceleration;
if(velocity < 0){
velocity = 0;
acceleration = 0;
@ -78,9 +96,14 @@ public class ClientParticleTree implements BehaviorTree {
if(hasLife){
lifeCurrent--;
if(lifeCurrent <= 0){
EntityUtils.cleanUpEntity(parent);
ClientEntityUtils.destroyEntity(parent);
}
}
//rotate the model to face the camera
Matrix4f rotationMatrix = new Matrix4f(Globals.viewMatrix).invert();
Quaternionf rotation = new Quaternionf(rotationMatrix.getRotation(new AxisAngle4f()));
EntityUtils.getRotation(parent).set(rotation);
}
/**

View File

@ -1,17 +1,20 @@
package electrosphere.entity.types.particle;
import electrosphere.engine.Globals;
import electrosphere.entity.DrawableUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.ParticleTree;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.state.particle.ClientParticleTree;
import electrosphere.game.data.particle.ParticleData;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorTextureMask;
import java.util.Arrays;
import org.joml.AxisAngle4f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -22,17 +25,7 @@ public class ParticleUtils {
// public static Entity clientSpawnBillboardProjectileParticle(String texture, int maxLife, Vector3f destination, float velocity, float acceleration){
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
// EntityCreationUtils.makeEntityDrawable(rVal, Globals.particleBillboardModel);
// EntityUtils.getActor(rVal).setTextureOverride(texture);
// Globals.assetManager.addTexturePathtoQueue(texture);
// ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
// rVal.putData(EntityDataStrings.TREE_CLIENTPARTICLETREE, particleTree);
// rVal.putData(EntityDataStrings.IS_PARTICLE, true);
// Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.PARTICLE);
// return rVal;
// }
public static Entity clientSpawnStaticBillboardParticle(){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
@ -43,19 +36,36 @@ public class ParticleUtils {
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.PARTICLE);
return rVal;
}
public static void makeParticleBillboardFaceCamera(Entity particle){
Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).add(cameraCenter).mul(-1.0f);
Vector3d particlePosition = EntityUtils.getPosition(particle);
// Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(1.0f,-1.0f,-1.0f);
// Vector3f directionVector = new Vector3f(cameraCenter).sub(cameraEye);
Matrix4f rotationMatrix = new Matrix4f(Globals.viewMatrix).invert();
Quaternionf rotation = new Quaternionf(rotationMatrix.getRotation(new AxisAngle4f()));
EntityUtils.getRotation(particle).set(rotation);
/**
* Spawns a billboard particle
* @param data The particle definition
* @param destination the destination of the particle
* @return The particle entity
*/
public static Entity clientSpawnBillboardParticle(ParticleData data, Vector3d destination){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, Globals.particleBillboardModel);
//actor logic
Actor particleActor = EntityUtils.getActor(rVal);
DrawableUtils.makeEntityTransparent(rVal);
particleActor.addTextureMask(new ActorTextureMask("particleBillboard", Arrays.asList(data.getTexture())));
//behavior tree attachments
ClientParticleTree.attachTree(rVal, data, destination);
rVal.putData(EntityDataStrings.IS_PARTICLE, true);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.PARTICLE);
return rVal;
}
public static ParticleTree getParticleTree(Entity particle){
return (ParticleTree)particle.getData(EntityDataStrings.TREE_CLIENTPARTICLETREE);
/**
* Checks if the provided entity is a particle or not
* @param entity The entity
* @return true if it is a particle, false otherwise
*/
public static boolean isParticle(Entity entity){
return entity.containsKey(EntityDataStrings.IS_PARTICLE);
}
}

View File

@ -13,6 +13,7 @@ import electrosphere.game.data.item.type.model.ItemTypeMap;
import electrosphere.game.data.object.type.ObjectData;
import electrosphere.game.data.object.type.model.ObjectTypeLoader;
import electrosphere.game.data.object.type.model.ObjectTypeMap;
import electrosphere.game.data.particle.ParticleDefinition;
import electrosphere.game.data.projectile.ProjectileTypeHolder;
import electrosphere.game.data.structure.type.model.StructureTypeMap;
import electrosphere.game.data.tutorial.HintDefinition;
@ -45,6 +46,11 @@ public class Config {
* The surface audio definitions
*/
SurfaceAudioCollection surfaceAudioCollection;
/**
* The particle definition
*/
ParticleDefinition particleDefinition;
/**
* Loads the default data
@ -63,6 +69,7 @@ public class Config {
config.projectileTypeHolder = FileUtils.loadObjectFromAssetPath("Data/projectile.json", ProjectileTypeHolder.class);
config.hintData = FileUtils.loadObjectFromAssetPath("Data/tutorial/hints.json", HintDefinition.class);
config.surfaceAudioCollection = FileUtils.loadObjectFromAssetPath("Data/audio/surface.json", SurfaceAudioCollection.class);
config.particleDefinition = FileUtils.loadObjectFromAssetPath("Data/particles.json", ParticleDefinition.class);
config.projectileTypeHolder.init();
//validate
@ -240,5 +247,13 @@ public class Config {
public SurfaceAudioCollection getSurfaceAudioCollection(){
return this.surfaceAudioCollection;
}
/**
* Gets the particle definition
* @return The particle definition
*/
public ParticleDefinition getParticleDefinition(){
return particleDefinition;
}
}

View File

@ -0,0 +1,102 @@
package electrosphere.game.data.particle;
/**
* Data on how a particle should behave
*/
public class ParticleData {
/**
* The name of the particle type
*/
String name;
/**
* The maximum life of the particle
*/
Integer maxLife;
/**
* The life the particle starts with
*/
Integer lifeCurrent;
/**
* The initial velocity of the particle
*/
Float velocity;
/**
* The acceleration of the particle
*/
Float acceleration;
/**
* The texture of the particle
*/
String texture;
/**
* The size of the particle
*/
Float size;
/**
* Gets the max life of the particle
* @return The max life
*/
public Integer getMaxLife(){
return maxLife;
}
/**
* Gets the starting life of the particle
* @return The starting life
*/
public Integer getLifeCurrent(){
return lifeCurrent;
}
/**
* Gets the starting velocity of the particle
* @return The starting velocity
*/
public Float getVelocity(){
return velocity;
}
/**
* Gets the acceleration of the particle
* @return The acceleration
*/
public Float getAcceleration(){
return acceleration;
}
/**
* Gets the texture of the particle
* @return The texture
*/
public String getTexture(){
return texture;
}
/**
* Gets the name of the particle type
* @return The name of the particle type
*/
public String getName(){
return name;
}
/**
* Gets the size of the particle
* @return The size of the particle
*/
public Float getSize(){
return size;
}
}

View File

@ -0,0 +1,23 @@
package electrosphere.game.data.particle;
import java.util.List;
/**
* File that defines all particles
*/
public class ParticleDefinition {
/**
* The particle data
*/
List<ParticleData> data;
/**
* Gets the particle data
* @return The particle data
*/
public List<ParticleData> getData(){
return data;
}
}

View File

@ -1,40 +0,0 @@
package electrosphere.game.server.effects;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.particle.ParticleUtils;
import java.util.Random;
import org.joml.Vector3f;
/**
* Utility functions for spawning particle effects
*/
public class ParticleEffects {
// public static void spawnSparks(Vector3f position, int min, int max){
// Random rand = new Random();
// int num = (int)(rand.nextFloat() * (max - min)) + min;
// for(int i = 0; i < num; i++){
// Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize();
// float velocity = rand.nextFloat() * 0.01f;
// float acceleration = 0.005f;
// Entity spark = ParticleUtils.clientSpawnBillboardProjectileParticle("Textures/spark1.png", 15, direction, velocity, acceleration);
// EntityUtils.getPosition(spark).set(position);
// EntityUtils.getScale(spark).mul(0.03f);
// }
// }
// public static void spawnBloodsplats(Vector3f position, int min, int max){
// Random rand = new Random();
// int num = (int)(rand.nextFloat() * (max - min)) + min;
// for(int i = 0; i < num; i++){
// Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize();
// float velocity = rand.nextFloat() * 0.001f;
// float acceleration = 0.000005f;
// Entity spark = ParticleUtils.clientSpawnBillboardProjectileParticle("Textures/bloodsplat1.png", 90, direction, velocity, acceleration);
// EntityUtils.getPosition(spark).set(position);
// EntityUtils.getScale(spark).mul(0.1f);
// }
// }
}

View File

@ -180,6 +180,15 @@ public class CombatMessage extends NetworkMessage {
if(currentStreamLength < 26 + hitboxTypeSize + hurtboxTypeSize){
return false;
}
if(currentStreamLength < 34 + hitboxTypeSize + hurtboxTypeSize){
return false;
}
if(currentStreamLength < 42 + hitboxTypeSize + hurtboxTypeSize){
return false;
}
if(currentStreamLength < 50 + hitboxTypeSize + hurtboxTypeSize){
return false;
}
return true;
}
@ -191,16 +200,22 @@ public class CombatMessage extends NetworkMessage {
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
rVal.sethitboxType(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
rVal.sethurtboxType(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
return rVal;
}
public static CombatMessage constructserverReportHitboxCollisionMessage(int entityID,int receiverEntityID,long time,String hitboxType,String hurtboxType){
public static CombatMessage constructserverReportHitboxCollisionMessage(int entityID,int receiverEntityID,long time,String hitboxType,String hurtboxType,double positionX,double positionY,double positionZ){
CombatMessage rVal = new CombatMessage(CombatMessageType.SERVERREPORTHITBOXCOLLISION);
rVal.setentityID(entityID);
rVal.setreceiverEntityID(receiverEntityID);
rVal.settime(time);
rVal.sethitboxType(hitboxType);
rVal.sethurtboxType(hurtboxType);
rVal.setpositionX(positionX);
rVal.setpositionY(positionY);
rVal.setpositionZ(positionZ);
rVal.serialize();
return rVal;
}
@ -211,7 +226,7 @@ public class CombatMessage extends NetworkMessage {
byte[] stringBytes;
switch(this.messageType){
case SERVERREPORTHITBOXCOLLISION:
rawBytes = new byte[2+4+4+8+4+hitboxType.length()+4+hurtboxType.length()];
rawBytes = new byte[2+4+4+8+4+hitboxType.length()+4+hurtboxType.length()+8+8+8];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_COMBAT;
//entity messaage header
@ -244,6 +259,18 @@ public class CombatMessage extends NetworkMessage {
for(int i = 0; i < hurtboxType.length(); i++){
rawBytes[26+hitboxType.length()+i] = stringBytes[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
for(int i = 0; i < 8; i++){
rawBytes[26+hitboxType.length()+hurtboxType.length()+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
for(int i = 0; i < 8; i++){
rawBytes[34+hitboxType.length()+hurtboxType.length()+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
for(int i = 0; i < 8; i++){
rawBytes[42+hitboxType.length()+hurtboxType.length()+i] = intValues[i];
}
break;
}
serialized = true;

View File

@ -150,7 +150,6 @@ public class RenderUtils {
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
};
//
@ -199,10 +198,10 @@ public class RenderUtils {
//
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8);
float[] texturedata = {
0,0,
1,0,
0,1,
1,1
1,1,
0,0,
1,0
};
texture_coords.put(texturedata);
texture_coords.flip();
@ -211,7 +210,7 @@ public class RenderUtils {
particleMesh.setShader(ShaderProgram.loadSpecificShader("Shaders/particleBillboard/particleBillboard.vs", "Shaders/particleBillboard/particleBillboard.fs"));
particleMesh.setShader(ShaderProgram.smartAssembleOITProgram(false, true));

View File

@ -4,28 +4,83 @@ import java.util.List;
import electrosphere.renderer.texture.Texture;
/**
* A mask that overwrites the texture for a given mesh for a given actor
*/
public class ActorTextureMask {
/**
* The mesh this mask is overwriting
*/
String meshName;
/**
* The texture objects used for this mask
*/
List<Texture> textures;
/**
* The paths to textures to be used for this mask
*/
List<String> texturePaths;
/**
* The uniform names used for this mask
*/
List<String> uniformNames;
/**
* Constructor
* @param meshName The name of the mesh to mask
* @param textures The texture objects to use to mask (ie diffuse and normal)
* @param uniformNames The uniform names used for each texture
*/
public ActorTextureMask(String meshName, List<Texture> textures, List<String> uniformNames){
this.meshName = meshName;
this.textures = textures;
this.uniformNames = uniformNames;
}
/**
* Constructor (does not use non-standard uniform names)
* @param meshName The name of the mesh to mask
* @param texturePaths The texture paths to use to mask
*/
public ActorTextureMask(String meshName, List<String> texturePaths){
this.meshName = meshName;
this.texturePaths = texturePaths;
}
/**
* Gets the name of the mesh this is masking
* @return The name of the mesh
*/
public String getMeshName(){
return meshName;
}
/**
* Gets the list of texture objects used to mask
* @return The list of texture objects
*/
public List<Texture> getTextures(){
return textures;
}
/**
* Gets the list of uniform names
* @return The list of uniform names
*/
public List<String> getUniformNames(){
return uniformNames;
}
/**
* Gets the texture paths to use
* @return The texture paths
*/
public List<String> getTexturePaths(){
return this.texturePaths;
}
}

View File

@ -397,25 +397,32 @@ public class Mesh {
//
//The texture masking logic
if(textureMask != null){
int i = 0;
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures"), 5);
// for(int j = 1; j < 15; j++){
// textureList.get(0).bind(j);
// }
for(Texture texture : textureMask.getTextures()){
// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i));
if(texture != null){
texture.bind(openGLState,5+i);
//
//path that uses already-defined texture objects
if(textureMask.getTextures() != null){
int i = 0;
for(Texture texture : textureMask.getTextures()){
if(texture != null){
texture.bind(openGLState,5+i);
}
glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), textureMask.getUniformNames().get(i)),5+i);
i++;
}
} else if(textureMask.getTexturePaths() != null){
//
//path that uses paths to textures in the asset manager
int i = 0;
for(String texturePath : textureMask.getTexturePaths()){
Texture texture = Globals.assetManager.fetchTexture(texturePath);
if(texture != null){
texture.bind(openGLState, i);
}
i++;
}
glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), textureMask.getUniformNames().get(i)),5+i);
i++;
}
// for(int j = i; j < 10; j++){
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j);
// }
// glActiveTexture(GL_TEXTURE0);
Globals.renderingEngine.checkError();
}

View File

@ -102,7 +102,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
if(isItem){
if(hitboxAttachParent != receiverParent){
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent);
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent);
}
}
@ -120,13 +120,13 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
//item is equipped to something
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(AttachUtils.getParent(receiverParent));
if(serverLifeTree != null){
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent);
}
} else {
//attacking an item that is not equipped to anything
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent);
if(serverLifeTree != null){
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent);
}
}

View File

@ -10,7 +10,6 @@ import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.particle.ParticleUtils;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.poseactor.PoseActor;
@ -49,12 +48,6 @@ public class MicroSimulation {
for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
ItemUtils.updateItemPoseActorAnimation(item);
}
//particle state updates
for(Entity particle : dataCell.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
// ParticleTree tree = ParticleUtils.getParticleTree(particle);
// tree.simulate(Main.deltaFrames);
ParticleUtils.makeParticleBillboardFaceCamera(particle);
}
//simulate behavior trees
dataCell.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
//update attached entity positions