No código abaixo, coloquei um exemplo de algo que quero fazer. Eu tenho a câmera e quero que ela pare de se mover sempre que atingir uma das caixas, como faço isso?
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();
}
}
Resultado:
java
collision-detection
3d
libgdx
SirMathhman
fonte
fonte
Respostas:
Os mecanismos de física que escrevi funcionam em três etapas
Cada quadro:
O mecanismo de física percorre os objetos e atualiza suas novas posições com base em
posição + = velocidade * deltaTime;
O mecanismo de física resolve todas as colisões
Primeiro, sugiro que, em vez de permitir que o FirstPersonCameraController defina a posição da câmera, torne a câmera um objeto físico, fazendo com que o FirstPersonCameraController controle a velocidade da câmera, não a posição, e deixe o mecanismo físico atualizar a posição da câmera.
Escrever um mecanismo de física pode parecer assustador, mas é realmente apenas um método que move todos os objetos em uma cena e garante que objetos sólidos não se sobreponham.
Por fim, dependendo de suas necessidades, existem duas abordagens que eu usei para resolver as colisões.
Depois que seu mecanismo de física moveu todos os objetos. Em seguida, faça um loop pelos objetos para ver quais estão sobrepostos. Se houver sobreposição, eles colidiram. Você precisa decidir como essa colisão será resolvida, mas geralmente isso significa que você move um ou ambos os objetos para trás até que eles não se sobreponham mais.
A maior desvantagem dessa abordagem é chamada de problema da bala através do papel. Se sua câmera estiver se movendo rápido o suficiente para atravessar um cubo inteiro em um quadro, quando você verificar colisões, não registrará se os dois objetos colidiram. Existem maneiras de superar isso, como garantir que nenhum objeto avance terrivelmente rápido e corrigir o timestep
Eu tive sucesso variado com este método. Basicamente, a idéia é que você pode combinar a fase de detecção de movimento e colisão para determinar que, considerando os vetores de velocidade de dois objetos, a que horas eles colidirão se realmente colidirem. Entrar em detalhes sobre como fazer isso está fora do escopo para esta resposta já longa, mas aqui está um bom artigo
Esse método resolve o problema através de um problema de papel, mas é mais difícil de entender / implementar, além de mais caro em termos de computação.
Pode haver mais métodos por aí que podem beneficiá-lo pesquisando na Internet para detecção de colisão.
fonte