/** Sets the quaternion components from the given axis and angle around that axis. * @param x X direction of the axis * @param y Y direction of the axis * @param z Z direction of the axis * @param radians The angle in radians * @return This quaternion for chaining. */ public Quaternion setFromAxisRad (final float x, final float y, final float z, final float radians) { float d = Vector3.len(x, y, z); if (d == 0f) return idt(); d = 1f / d; float l_ang = radians < 0 ? MathUtils.PI2 - (-radians % MathUtils.PI2) : radians % MathUtils.PI2; float l_sin = (float)Math.sin(l_ang / 2); float l_cos = (float)Math.cos(l_ang / 2); return this.set(d * x * l_sin, d * y * l_sin, d * z * l_sin, l_cos).nor(); }
/** Sets the quaternion components from the given axis and angle around that axis. * @param x X direction of the axis * @param y Y direction of the axis * @param z Z direction of the axis * @param radians The angle in radians * @return This quaternion for chaining. */ public Quaternion setFromAxisRad (final float x, final float y, final float z, final float radians) { float d = Vector3.len(x, y, z); if (d == 0f) return idt(); d = 1f / d; float l_ang = radians < 0 ? MathUtils.PI2 - (-radians % MathUtils.PI2) : radians % MathUtils.PI2; float l_sin = (float)Math.sin(l_ang / 2); float l_cos = (float)Math.cos(l_ang / 2); return this.set(d * x * l_sin, d * y * l_sin, d * z * l_sin, l_cos).nor(); }
private void endpart () { if (part != null) { bounds.getCenter(part.center); bounds.getDimensions(part.halfExtents).scl(0.5f); part.radius = part.halfExtents.len(); bounds.inf(); part.offset = istart; part.size = indices.size - istart; istart = indices.size; part = null; } }
/** Calculates and updates the {@link #center}, {@link #halfExtents} and {@link #radius} values. This is considered a costly * operation and should not be called frequently. All vertices (points) of the shape are traversed to calculate the maximum and * minimum x, y and z coordinate of the shape. Note that MeshPart is not aware of any transformation that might be applied when * rendering. It calculates the untransformed (not moved, not scaled, not rotated) values. */ public void update () { mesh.calculateBoundingBox(bounds, offset, size); bounds.getCenter(center); bounds.getDimensions(halfExtents).scl(0.5f); radius = halfExtents.len(); }
/** Calculates and updates the {@link #center}, {@link #halfExtents} and {@link #radius} values. This is considered a costly * operation and should not be called frequently. All vertices (points) of the shape are traversed to calculate the maximum and * minimum x, y and z coordinate of the shape. Note that MeshPart is not aware of any transformation that might be applied when * rendering. It calculates the untransformed (not moved, not scaled, not rotated) values. */ public void update () { mesh.calculateBoundingBox(bounds, offset, size); bounds.getCenter(center); bounds.getDimensions(halfExtents).scl(0.5f); radius = halfExtents.len(); }
private void endpart () { if (part != null) { bounds.getCenter(part.center); bounds.getDimensions(part.halfExtents).scl(0.5f); part.radius = part.halfExtents.len(); bounds.inf(); part.offset = istart; part.size = indices.size - istart; istart = indices.size; part = null; } }
/** Compute final result. * @param bb BoundingBox encompassing instances * @param camera Camera to compute */ protected void computeResult (BoundingBox bb, Camera camera) { // Radius float radius = bb1.getDimensions(tmpV).len() * 0.5f; // Center bb1.getCenter(tmpV); // Computation float distance = tmpV.dst(camera.position); float near = distance - radius; float far = distance + radius; if (near <= 0) near = CAMERA_NEAR; if (far <= 0) far = CAMERA_FAR; camera.near = near; camera.far = far; camera.update(); } }
@Override protected void onLoaded () { if (currentlyLoading == null || currentlyLoading.length() == 0) return; instances.clear(); animationControllers.clear(); final ModelInstance instance = new ModelInstance(assets.get(currentlyLoading, Model.class)); instance.transform = transform; instances.add(instance); if (instance.animations.size > 0) animationControllers.put(instance, new AnimationController(instance)); currentlyLoading = null; instance.calculateBoundingBox(bounds); cam.position.set(1, 1, 1).nor().scl(bounds.getDimensions(tmpV1).len() * 0.75f + bounds.getCenter(tmpV2).len()); cam.up.set(0, 1, 0); cam.lookAt(0, 0, 0); cam.far = 50f + bounds.getDimensions(tmpV1).len() * 2.0f; cam.update(); }
public BulletEntity (final ModelInstance modelInstance, final btCollisionObject body) { this.modelInstance = modelInstance; this.transform = this.modelInstance.transform; this.body = body; modelInstance.calculateBoundingBox(boundingBox); boundingBoxRadius = boundingBox.getDimensions(new Vector3()).len() * 0.5f; if (body != null) { body.userData = this; if (body instanceof btRigidBody) { this.motionState = new MotionState(this.modelInstance.transform); ((btRigidBody)this.body).setMotionState(motionState); } else body.setWorldTransform(transform); } }
cam.position.set(1, 1, 1).nor().scl(bounds.getDimensions(tmpV).len() * 0.75f).add(bounds.getCenter(tmpV)); cam.up.set(0, 1, 0); cam.lookAt(inputController.target.set(bounds.getCenter(tmpV))); cam.far = Math.max(100f, bounds.getDimensions(tmpV).len() * 2.0f); cam.update(); moveRadius = bounds.getDimensions(tmpV).len() * 0.25f;
frustumCam.far = Vector3.len(BOX_X_MAX, BOX_Y_MAX, BOX_Z_MAX); frustumCam.update();
@Override public void create () { super.create(); instructions = "Tap to toggle view\nLong press to toggle debug mode\nSwipe for next test\nCtrl+drag to rotate\nScroll to zoom"; tempManifoldArr = new btPersistentManifoldArray(); world.addConstructor("collisionBox", new BulletConstructor(world.getConstructor("box").model)); // Create the entities final float dX = BOX_X_MAX - BOX_X_MIN; final float dY = BOX_Y_MAX - BOX_Y_MIN; final float dZ = BOX_Z_MAX - BOX_Z_MIN; for (int i = 0; i < BOXCOUNT; i++) world.add("collisionBox", BOX_X_MIN + dX * (float)Math.random(), BOX_Y_MIN + dY * (float)Math.random(), BOX_Z_MIN + dZ * (float)Math.random()).setColor(Color.GRAY); frustumCam = new PerspectiveCamera(camera.fieldOfView, camera.viewportWidth, camera.viewportHeight); frustumCam.far = Vector3.len(BOX_X_MAX, BOX_Y_MAX, BOX_Z_MAX); frustumCam.update(); overviewCam = camera; overviewCam.position.set(BOX_X_MAX, BOX_Y_MAX, BOX_Z_MAX); overviewCam.lookAt(Vector3.Zero); overviewCam.far = 150f; overviewCam.update(); final Model frustumModel = createFrustumModel(frustumCam.frustum.planePoints); disposables.add(frustumModel); frustumObject = createFrustumObject(frustumCam.frustum.planePoints); world.add(frustumEntity = new BulletEntity(frustumModel, frustumObject, 0, 0, 0)); frustumEntity.setColor(Color.BLUE); }
/** Returns whether the given line segment intersects the given circle. * @param start The start point of the line segment * @param end The end point of the line segment * @param center The center of the circle * @param squareRadius The squared radius of the circle * @return Whether the line segment and the circle intersect */ public static boolean intersectSegmentCircle (Vector2 start, Vector2 end, Vector2 center, float squareRadius) { tmp.set(end.x - start.x, end.y - start.y, 0); tmp1.set(center.x - start.x, center.y - start.y, 0); float l = tmp.len(); float u = tmp1.dot(tmp.nor()); if (u <= 0) { tmp2.set(start.x, start.y, 0); } else if (u >= l) { tmp2.set(end.x, end.y, 0); } else { tmp3.set(tmp.scl(u)); // remember tmp is already normalized tmp2.set(tmp3.x + start.x, tmp3.y + start.y, 0); } float x = center.x - tmp2.x; float y = center.y - tmp2.y; return x * x + y * y <= squareRadius; }
/** Returns whether the given line segment intersects the given circle. * @param start The start point of the line segment * @param end The end point of the line segment * @param center The center of the circle * @param squareRadius The squared radius of the circle * @return Whether the line segment and the circle intersect */ public static boolean intersectSegmentCircle (Vector2 start, Vector2 end, Vector2 center, float squareRadius) { tmp.set(end.x - start.x, end.y - start.y, 0); tmp1.set(center.x - start.x, center.y - start.y, 0); float l = tmp.len(); float u = tmp1.dot(tmp.nor()); if (u <= 0) { tmp2.set(start.x, start.y, 0); } else if (u >= l) { tmp2.set(end.x, end.y, 0); } else { tmp3.set(tmp.scl(u)); // remember tmp is already normalized tmp2.set(tmp3.x + start.x, tmp3.y + start.y, 0); } float x = center.x - tmp2.x; float y = center.y - tmp2.y; return x * x + y * y <= squareRadius; }
@Override protected void onLoaded () { super.onLoaded(); BoundingBox bounds = instances.get(0).calculateBoundingBox(new BoundingBox()); bounds.getCenter(center); radius = bounds.getDimensions(tmpV).len() * .5f; pointLight.position.set(0, radius, 0).add(transformedCenter.set(center).mul(transform)); pointLight.intensity = radius * radius; ((ColorAttribute)pLight.material.get(ColorAttribute.Diffuse)).color.set(pointLight.color); final float s = 0.2f * radius; pLight.worldTransform.setToScaling(s, s, s); }
float radius = bb.getDimensions(tmpV).len() * 0.5f;
/** Build Camera with custom colors * @param builder * @param camera * @param frustumColor * @param coneColor * @param upColor * @param targetColor * @param crossColor */ public static void build (MeshPartBuilder builder, Camera camera, Color frustumColor, Color coneColor, Color upColor, Color targetColor, Color crossColor) { Vector3[] planePoints = camera.frustum.planePoints; // Frustum build(builder, camera.frustum, frustumColor, crossColor); // Cones (camera position to near plane) builder.line(planePoints[0], coneColor, camera.position, coneColor); builder.line(planePoints[1], coneColor, camera.position, coneColor); builder.line(planePoints[2], coneColor, camera.position, coneColor); builder.line(planePoints[3], coneColor, camera.position, coneColor); // Target line builder.line(camera.position, targetColor, centerPoint(planePoints[4], planePoints[5], planePoints[6]), targetColor); // Up triangle float halfNearSize = tmpV0.set(planePoints[1]).sub(planePoints[0]).scl(0.5f).len(); Vector3 centerNear = centerPoint(planePoints[0], planePoints[1], planePoints[2]); tmpV0.set(camera.up).scl(halfNearSize * 2); centerNear.add(tmpV0); builder.line(centerNear, upColor, planePoints[2], upColor); builder.line(planePoints[2], upColor, planePoints[3], upColor); builder.line(planePoints[3], upColor, centerNear, upColor); }
/** Build Camera with custom colors * @param builder * @param camera * @param frustumColor * @param coneColor * @param upColor * @param targetColor * @param crossColor */ public static void build (MeshPartBuilder builder, Camera camera, Color frustumColor, Color coneColor, Color upColor, Color targetColor, Color crossColor) { Vector3[] planePoints = camera.frustum.planePoints; // Frustum build(builder, camera.frustum, frustumColor, crossColor); // Cones (camera position to near plane) builder.line(planePoints[0], coneColor, camera.position, coneColor); builder.line(planePoints[1], coneColor, camera.position, coneColor); builder.line(planePoints[2], coneColor, camera.position, coneColor); builder.line(planePoints[3], coneColor, camera.position, coneColor); // Target line builder.line(camera.position, targetColor, centerPoint(planePoints[4], planePoints[5], planePoints[6]), targetColor); // Up triangle float halfNearSize = tmpV0.set(planePoints[1]).sub(planePoints[0]).scl(0.5f).len(); Vector3 centerNear = centerPoint(planePoints[0], planePoints[1], planePoints[2]); tmpV0.set(camera.up).scl(halfNearSize * 2); centerNear.add(tmpV0); builder.line(centerNear, upColor, planePoints[2], upColor); builder.line(planePoints[2], upColor, planePoints[3], upColor); builder.line(planePoints[3], upColor, centerNear, upColor); }
@Override public boolean touchDown (int screenX, int screenY, int pointer, int button) { boolean result = false; if (button == Buttons.LEFT) { Ray ray = camera.getPickRay(screenX, screenY); tmpV1.set(ray.direction).scl(10f).add(ray.origin); ClosestRayResultCallback cb = new ClosestRayResultCallback(ray.origin, tmpV1); world.collisionWorld.rayTest(ray.origin, tmpV1, cb); if (cb.hasHit()) { btRigidBody body = (btRigidBody)(cb.getCollisionObject()); if (body != null && !body.isStaticObject() && !body.isKinematicObject()) { pickedBody = body; body.setActivationState(Collision.DISABLE_DEACTIVATION); cb.getHitPointWorld(tmpV); tmpV.mul(body.getCenterOfMassTransform().inv()); pickConstraint = new btPoint2PointConstraint(body, tmpV); btConstraintSetting setting = pickConstraint.getSetting(); setting.setImpulseClamp(30f); setting.setTau(0.001f); pickConstraint.setSetting(setting); ((btDynamicsWorld)world.collisionWorld).addConstraint(pickConstraint); pickDistance = tmpV1.sub(camera.position).len(); result = true; } } cb.dispose(); } return result ? result : super.touchDown(screenX, screenY, pointer, button); }