All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tenio.engine.physic2d.utility.EntitiesRelationship Maven / Gradle / Ivy

Go to download

TenIO is a java NIO (Non-blocking I/O) based server specifically designed for multiplayer games. It supports UDP and TCP transports which are handled by Netty for high-speed network transmission. This is the engine module for the game related handlers of the framework.

There is a newer version: 0.6.0
Show newest version
package com.tenio.engine.physic2d.utility;

import com.tenio.common.utility.MathUtility;
import com.tenio.engine.physic2d.common.BaseGameEntity;
import com.tenio.engine.physic2d.math.Vector2;
import java.util.LinkedList;
import java.util.List;

/**
 * Some useful entities functions.
 * 
* 3D * Matrix Transforms */ public final class EntitiesRelationship { // Tests to see if an entity is overlapping any of a number of entities stored // in a list container public static > boolean isOverlapped( T ob, CT conOb) { return isOverlapped(ob, conOb, 40); } /** * Check if there is overlap between entities. * * @param ob the ob * @param conOb the conOb * @param minDistBetweenObstacles the min distance between obstacles * @param the T class * @param the CT class * @return return true if there is overlap, false otherwise */ public static > boolean isOverlapped( T ob, CT conOb, float minDistBetweenObstacles) { var it = conOb.listIterator(); while (it.hasNext()) { var tmp = it.next(); if (Geometry.isTwoCirclesOverlapped(ob.getPosition(), ob.getBoundingRadius() + minDistBetweenObstacles, tmp.getPosition(), tmp.getBoundingRadius())) { return true; } } return false; } /** * Tags any entities contained in a list container that are within the radius of * the single entity parameter. * * @param entity the entity * @param containerOfEntities the container of entities * @param radius the radius * @param the T class * @param the CT class */ public static > void tagNeighbors( final T entity, CT containerOfEntities, float radius) { // iterate through all entities checking for range containerOfEntities.forEach(neighborEntity -> { if (neighborEntity != entity) { // compare pointers // first clear any current tag neighborEntity.enableTag(false); var temp = Vector2.newInstance().set(neighborEntity.getPosition()).sub(entity.getPosition()); // the bounding radius of the other is taken into account by adding it // to the range float range = radius + neighborEntity.getBoundingRadius(); // if entity within range, tag for further consideration. (working in // distance-squared space to avoid sqrts) if ((temp.getLengthSqr() < range * range)) { neighborEntity.enableTag(true); } } }); } /** * Given a pointer to an entity and a list container of pointers to nearby * entities, this function checks to see if there is an overlap between * entities. If there is, then the entities are moved away from each other. * * @param entity the entity * @param containerOfEntities the container of entities * @param the T class * @param the CT class */ public static > void enforceNonPenetrationConstraint( final T entity, final CT containerOfEntities) { // iterate through all entities checking for any overlap of bounding radius var it = containerOfEntities.listIterator(); while (it.hasNext()) { var curEntity = it.next(); // make sure we don't check against the individual if (curEntity == entity) { continue; } // calculate the distance between the positions of the entities var temp = Vector2.newInstance().set(entity.getPosition()).sub(curEntity.getPosition()); float distFromEachOther = temp.getLength(); // if this distance is smaller than the sum of their radius then this // entity must be moved away in the direction parallel to the // ToEntity vector float amountOfOverLap = curEntity.getBoundingRadius() + entity.getBoundingRadius() - distFromEachOther; if (amountOfOverLap >= 0) { // move the entity a distance away equivalent to the amount of overlap. /* * Temp = (EntityPosition - CurrentEntityPosition); Distance = Temp->getLength; * NewPosition = EntityPosition + ((Temp / Distance) * Amount) */ temp.div(distFromEachOther).mul(amountOfOverLap).add(entity.getPosition()); entity.setPosition(temp); } } // next entity } // Tests a line segment AB against a container of entities. First, a test // is made to confirm that the entity is within a specified range of the // one_to_ignore (positioned at vectorA). If within range the intersection test is // made. // // returns a list of all the entities that tested positive for intersection public static > List getEntityLineSegmentIntersections( final CT entities, String theOneToIgnore, Vector2 vectorA, Vector2 vectorB) { return getGetEntityLineSegmentIntersections(entities, theOneToIgnore, vectorA, vectorB, MathUtility.MAX_FLOAT); } /** * Retrieves the entity line segment intersections. * * @param entities the list of entities * @param theOneToIgnore the one to ignore * @param vectorA the vector A * @param vectorB the vector B * @param range the range * @param the T class * @param the CT class * @return the list of hit entities */ public static > List getGetEntityLineSegmentIntersections( final CT entities, String theOneToIgnore, Vector2 vectorA, Vector2 vectorB, float range) { var it = entities.listIterator(); var hits = new LinkedList(); // iterate through all entities checking against the line segment AB while (it.hasNext()) { var curEntity = it.next(); // if not within range or the entity being checked is the_one_to_ignore // just continue with the next entity float distance = Vector2.newInstance().set(curEntity.getPosition()) .getDistanceSqrValue(vectorA); if ((curEntity.getId().equals(theOneToIgnore)) || distance > range * range) { continue; } // if the distance to AB is less than the entities bounding radius then // there is an intersection so add it to hits if (Geometry.getDistancePointSegment(vectorA, vectorB, curEntity.getPosition()) < curEntity.getBoundingRadius()) { hits.add(curEntity); } } return hits; } // Tests a line segment AB against a container of entities. First, a test // is made to confirm that the entity is within a specified range of the // one_to_ignore (positioned at vectorA). If within range the intersection test is // made. // returns the closest entity that tested positive for intersection or NULL if // none found public static > T getClosestEntityLineSegmentIntersection( final CT entities, String theOneToIgnore, Vector2 vectorA, Vector2 vectorB) { return getClosestEntityLineSegmentIntersection(entities, theOneToIgnore, vectorA, vectorB, MathUtility.MAX_FLOAT); } /** * Retrieves the closest entity line segment intersections. * * @param entities the list of entities * @param theOneToIgnore the one to ignore * @param vectorA the vector A * @param vectorB the vector B * @param range the range * @param the T class * @param the CT class * @return the closest entity */ public static > T getClosestEntityLineSegmentIntersection( final CT entities, String theOneToIgnore, Vector2 vectorA, Vector2 vectorB, float range) { var it = entities.listIterator(); T closestEntity = null; float closestDist = MathUtility.MAX_FLOAT; // iterate through all entities checking against the line segment AB while (it.hasNext()) { T curEntity = it.next(); float distSq = Vector2.newInstance().set(curEntity.getPosition()) .getDistanceSqrValue(vectorA); // if not within range or the entity being checked is the_one_to_ignore // just continue with the next entity if ((curEntity.getId().equals(theOneToIgnore)) || (distSq > range * range)) { continue; } // if the distance to AB is less than the entities bounding radius then // there is an intersection so add it to hits if (Geometry.getDistancePointSegment(vectorA, vectorB, curEntity.getPosition()) < curEntity.getBoundingRadius()) { if (distSq < closestDist) { closestDist = distSq; closestEntity = curEntity; } } } return closestEntity; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy