중복으로 표시하기 전에. 나는 네가 비슷하게 말한 제목에 몇 가지 질문이 있다는 것을 알고 싶다. 그러나 나는 그것들을 읽었으며 그것들은 크게 다르다.3D Collision Mesh (보다 효율적인 충돌 계산)
저는 최근에 가장 복잡한 3D 메시에서부터 가장 복잡한 3D 메시에 이르기까지 어디에서나 충돌을 감지하는 완벽한 시스템을 완성했습니다. 문제는 내 엔진에서 게임 플레이 경험이 매우 비효율적이고 비용이 많이 든다는 것입니다. 부수적으로, 나는이 코드를 완벽하게 만들었다. 아무런 참고 문헌도없이이 충돌을 독자적으로 처리 할 수 있는지 알아보기 위해. 엉망으로해서 미안해. 그래서 더 이상 신경 쓰지 않고 여기에 중요한 코드가 있습니다.
package nope;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
import net.aionstudios.nightfall.entities.Entity;
import net.aionstudios.nightfall.renderEngine.model.TexturedModel;
public class ColliderEntity extends Entity {
private List<CollisionMesh> entityBounds = new ArrayList<CollisionMesh>();
private boolean alertCollisions = false;
public ColliderEntity(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale, BoundingBox entityBounds) {
super(model, position, rotX, rotY, rotZ, scale);
this.entityBounds.add(entityBounds);
}
public List<ColliderEntity> detectImpact(List<ColliderEntity> colliders){
List<ColliderEntity> colE = new ArrayList<ColliderEntity>();
colE.clear();
for (ColliderEntity ce : colliders) {
if(ce != this) {
Vector3f boundsOffsets = new Vector3f(difference(this.getPosition().x, ce.getPosition().x), difference(this.getPosition().y, ce.getPosition().y), difference(this.getPosition().z, ce.getPosition().z));
boolean xCollide = false;
boolean yCollide = false;
boolean zCollide = false;
for (CollisionMesh b1 : this.getEntityBounds()){
for(MeshPoint mp : b1.getPoints()){
List<Vector3f> points = mp.getConnectionsAndPoint();
for (CollisionMesh b2 : ce.getEntityBounds()) {
for(MeshPoint mp2 : b2.getPoints()){
List<Vector3f> points2 = mp2.getConnectionsAndPoint();
for (Vector3f pt : points2){
pt = new Vector3f(pt.x-boundsOffsets.x, pt.y-boundsOffsets.y, pt.z-boundsOffsets.z);
for (int i = 1; i < points.size(); i++){
if(!xCollide || !yCollide || !zCollide){
if(points.get(i-1).x > pt.x && pt.x > points.get(i).x) {
xCollide = true;
}
if(points.get(i-1).y > pt.y && pt.y > points.get(i).y) {
yCollide = true;
}
if(points.get(i-1).z > pt.z && pt.z > points.get(i).z) {
zCollide = true;
}
}
}
}
if(!!xCollide || !yCollide || !zCollide){
for (Vector3f pts : points){
pts = new Vector3f(pts.x-boundsOffsets.x, pts.y-boundsOffsets.y, pts.z-boundsOffsets.z);
for (int i = 1; i < points2.size(); i++){
if(!xCollide || !yCollide || !zCollide){
if(points2.get(i-1).x > pts.x && pts.x > points2.get(i).x) {
xCollide = true;
}
if(points2.get(i-1).y > pts.y && pts.y > points2.get(i).y) {
yCollide = true;
}
if(points2.get(i-1).z > pts.z && pts.z > points2.get(i).z) {
zCollide = true;
}
}
}
}
}
if(xCollide && yCollide && zCollide){
colE.add(ce);
if(alertCollisions) {
System.out.println("Collision on Entity "+this.toString()+" at: "+this.getPosition().x+" "+this.getPosition().y+" "+this.getPosition().z+" with Entity "+ce.toString()+" at: "+ce.getPosition().x+" "+ce.getPosition().y+" "+ce.getPosition().z);
}
}
}
}
}
}
}
}
return colE;
}
private float difference(float x, float x1){
float dx = x - x1;
return (float) Math.sqrt(dx * dx);
}
public boolean isAlertCollisions() {
return alertCollisions;
}
public void setAlertCollisions(boolean alertCollisions) {
this.alertCollisions = alertCollisions;
}
public List<CollisionMesh> getEntityBounds() {
return entityBounds;
}
public void addEntityBounds(BoundingBox b){
this.entityBounds.add(b);
}
public void removeEntityBounds(BoundingBox b){
this.entityBounds.remove(entityBounds);
}
}
이 클래스는 충돌 메시가있는 엔티티입니다. 그리고 충격 감지. 여기에 무슨 일이 일어나고 있는지 이해하려면 좀 더 통찰력이 필요합니다.
package nope;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
public class CollisionMesh {
private List<MeshPoint> points = new ArrayList<MeshPoint>();
public CollisionMesh(MeshPoint[] points){
for(MeshPoint p : points){
this.points.add(p);
}
}
public List<MeshPoint> getPoints() {
return points;
}
public void addMeshPoint(MeshPoint point){
for (MeshPoint p : points){
if(point == p){
return;
}
}
points.add(point);
}
public void removeMeshPoint(MeshPoint point){
for(MeshPoint p : points){
if(p == point){
points.remove(point);
return;
}
}
cleanupMeshPoints();
}
public void cleanupMeshPoints(){
for(MeshPoint p : points){
for(Vector3f pi : p.getConnections()){
boolean connected = false;
for(MeshPoint p2 : points){
if(p2.getPoint() == pi){
connected = true;
}
}
if(!connected){
p.getConnections().remove(pi);
}
}
}
}
}
이것은 충돌 가능한 엔티티에 제공된 충돌 메쉬이며, 연결을 저장하는 개별 메쉬 포인트로 구성됩니다. 그 클래스는 다음과 같습니다.
package nope;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
public class MeshPoint {
private Vector3f point;
private List<Vector3f> connections = new ArrayList<Vector3f>();
public MeshPoint(Vector3f point, Vector3f[] connections){
this.point = point;
for(Vector3f connection : connections){
this.connections.add(connection);
}
}
public Vector3f getPoint() {
return point;
}
public void setPoint(Vector3f point) {
this.point = point;
}
public List<Vector3f> getConnections() {
return connections;
}
public List<Vector3f> getConnectionsAndPoint() {
List<Vector3f> cp = connections;
cp.add(this.point);
return cp;
}
public void addConnection(Vector3f connection){
for (Vector3f c : connections){
if(c.x == connection.x && c.y == connection.y && c.z == connection.z){
return;
}
}
connections.add(connection);
}
public void removeConnection(Vector3f connection){
for (Vector3f c : connections){
if(c.x == connection.x && c.y == connection.y && c.z == connection.z){
connections.remove(connection);
return;
}
}
}
}
메쉬 연결은 게임의 프레임 속도를 실제로 죽이고 있다고 생각합니다. 2 개의 상자처럼 단순한 객체가 활성화 된 경우 120의 프레임 뚜껑에서 일반적으로 약 3까지 떨어집니다. 몇 가지 문제를 식별 할 수 있지만이 코드를 현재보다 덜 복잡하게 만들 수는 없습니다. 어떤 도움이라도 대단히 감사합니다.
나는 이와 같은 질문이 일반적으로 잘 받아 들여지지 않을 것이고 여기에 오는 많은 사람들은 최소한의 완전한 예제를 찾고있을 것입니다.하지만이 사실을 확인하기 위해 할 일이 전혀 없었습니다. 그렇습니다.
코드를 프로파일 링했는지 궁금하십니까? 비효율적 인 코드의 특정 영역을 강조 표시하면 대답하는 것이 더 쉬울 수도 있습니다. 메쉬 연결이라고 생각한다고 말씀하셨습니다. 그러나 코드 검사를 통해 성능 병목 현상을 추측하는 것은 매우 어렵습니다. 프로파일 링은 튜닝 노력에 집중하기 위해 내가해야 할 첫 번째 일이 될 것입니다. – sprinter
물어 보는 질문에 대해 더 명확히 할 수 있습니까? 문제를 설명합니다 ("내 엔진에서 게임 플레이 경험에 비싸고 비효율적이며 비용이 많이 듭니다.").하지만 우리가 원하는 도움이나 어떤 부분을 조사해야하는지 명시 적으로 나타내지는 않습니다. –
필자는 Bullet 라이브러리 (예, Java라고 알고 있음)와 Broad Phase, Narrow Phase의 개념을 항상 이렇게 지적합니다. 광역 단계는 교차 할 수있는 요소 (구형 구체, 상자 상자 등)를 매우 빠르게 결정합니다. 좁은 위상은 엄격하고 느린 삼각형 교차 테스트입니다.이 테스트는 모델에있는 메타 데이터에 따라 광범위하게/좁게 나누어 질 수 있습니다. – Robinson