Dans le code ci-dessous, j'ai mis un exemple de quelque chose que je veux faire. J'ai la caméra et je veux qu'elle cesse de bouger à chaque fois qu'elle touche une des boîtes, comment faire?
public class Main extends ApplicationAdapter {
private final ModelBuilder builder = new ModelBuilder();
private final Environment environment = new Environment();
private ModelBatch modelBatch;
private PerspectiveCamera camera;
private Model model;
private ArrayList<ModelInstance> instance = new ArrayList<ModelInstance>();
private FirstPersonCameraController controller;
private BoundingBox[] boxBounds = new BoundingBox[1000];
private BoundingBox cameraBox = new BoundingBox();
private Vector3 cameraSpeed = new Vector3();
private Vector3 oldCameraPos = new Vector3();
private Vector3 newCameraPos = new Vector3();
@Override
public void create() {
modelBatch = new ModelBatch();
//build the camera
camera = new PerspectiveCamera(67, graphics.getWidth(), graphics.getHeight());
camera.position.set(0f, 10f, 0f);
camera.lookAt(0, 10, 0);
camera.near = 1f;
camera.far = 1000f;
camera.update();
//build all the boxes
for (int i = 0; i < 1000; i++) {
model = builder.createBox(
(float) Math.random() * 50,
(float) Math.random() * 50,
(float) Math.random() * 50,
new Material(ColorAttribute.createDiffuse(
(float) random(),
(float) random(),
(float) random(), 1)
), Position | Normal);
instance.add(new ModelInstance(model));
instance.get(i).transform.setToTranslation(
(float) random() * 1000 - 500,
(float) random() * 1000,
(float) random() * 1000 - 500);
boxBounds[i] = new BoundingBox();
boxBounds[i] = model.calculateBoundingBox(boxBounds[i]);
}
//build the ground
model = builder.createBox(700f, 1f, 700f, new Material(ColorAttribute.createDiffuse(Color.GREEN)), Position | Normal);
ModelInstance ground = new ModelInstance(model);
instance.add(ground);
//build the center
model = builder.createBox(5f, 5f, 5f, new Material(ColorAttribute.createDiffuse(Color.RED)), Position | Normal);
ModelInstance center = new ModelInstance(model);
instance.add(center);
//code the lights here
DirectionalLight light = new DirectionalLight().set(255, 255, 255,
(float) random(),
(float) random(),
(float) random());
//set up the enviroment
environment.set(new ColorAttribute(AmbientLight, 255f, 255f, 255f, 1f));
environment.add(light);
//set up the camera controller
controller = new FirstPersonCameraController(camera);
controller.setDegreesPerPixel(0.25f);
controller.setVelocity(20);
input.setInputProcessor(controller);
}
@Override
public void render() {
//set up OpenGL
gl.glViewport(0, 0, graphics.getWidth(), graphics.getHeight());
gl.glEnable(GL_BLEND);
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0, 0, 0, 0);
//render the modelInstances
modelBatch.begin(camera);
modelBatch.render(instance, environment);
modelBatch.end();
controller.update();
if (input.isKeyPressed(Input.Keys.R)) {
camera.lookAt(0, 0, 0);
}
cameraSpeed = newCameraPos.sub(oldCameraPos);
cameraBox = new BoundingBox(new Vector3(camera.position.x,
camera.position.y,
camera.position.z),
new Vector3(camera.position.x + 10,
camera.position.y + 10,
camera.position.z + 10));
for (int i = 0; i < 1000; i++) {
if (cameraBox.contains(boxBounds[i])) {
camera.position.x = camera.position.x - cameraSpeed.x;
camera.position.y = camera.position.y - cameraSpeed.y;
camera.position.z = camera.position.z - cameraSpeed.z;
}
}
System.out.println(cameraSpeed.x + " " + cameraSpeed.y + " " + cameraSpeed.z);
}
@Override
public void dispose() {
modelBatch.dispose();
model.dispose();
}
}
Résultat:
java
collision-detection
3d
libgdx
SirMathhman
la source
la source
Réponses:
Les moteurs physiques que j'ai écrits fonctionnent en trois étapes
Chaque image:
Le moteur physique parcourt les objets et met à jour leurs nouvelles positions en fonction de
position + = vitesse * deltaTime;
Le moteur physique résout toutes les collisions
Tout d'abord, je suggère qu'au lieu de laisser votre FirstPersonCameraController définir la position de la caméra, faire de la caméra un objet physique en faisant en sorte que le FirstPersonCameraController contrôle la vitesse de la caméra, pas sa position, puis en laissant le moteur physique mettre à jour la position de la caméra.
L'écriture d'un moteur physique peut sembler effrayante, mais c'est vraiment juste une méthode qui déplace tous les objets d'une scène et s'assure ensuite que les objets solides ne se chevauchent pas.
Enfin, selon vos besoins, il y a deux approches que j'ai utilisées pour résoudre les collisions.
Une fois que votre moteur physique a déplacé chaque objet. Parcourez ensuite les objets pour voir ceux qui se chevauchent. Si certains se chevauchent, ils sont entrés en collision. Vous devez décider comment cette collision sera résolue, mais cela signifie généralement que vous déplacez un ou les deux objets vers l'arrière jusqu'à ce qu'ils ne se chevauchent plus.
Le plus gros inconvénient de cette approche est le problème du papier à travers le papier. Si votre caméra se déplace assez rapidement pour traverser un cube entier dans une seule image, alors lorsque vous vérifiez les collisions, vous n'enregistrez pas que les deux objets sont entrés en collision. Il existe des moyens de surmonter cela, par exemple en vous assurant qu'aucun objet ne va horriblement vite et en fixant votre pas de temps
J'ai eu différents succès avec cette méthode. Fondamentalement, l'idée est que vous pouvez combiner la phase de détection de mouvement et de collision pour déterminer que, étant donné les vecteurs de vitesse de deux objets, à quelle heure vont-ils entrer en collision s'ils entrent en collision? Aller en profondeur sur la façon d'y parvenir est hors de portée pour cette réponse déjà longue, mais voici un bon article
Cette méthode résout la balle à travers un problème de papier, mais elle est plus difficile à comprendre / implémenter et plus coûteuse en calcul.
Il existe peut-être d'autres méthodes qui pourraient vous être utiles en recherchant sur Internet la détection des collisions.
la source