public void update(float delta, Camera c) { heal(healthregen * delta); regenerateMana(manaregen * delta); if (!isJumping && input.isJumpPressed()) { characterController.jump(); animations.setAnimation("Jumping"); isJumping = true; } else { isJumping = false; } if (!isPerformingRightAction && input.isRightHandPressed()) { isPerformingRightAction = true; rightweapon.onAttackStart(); rightActionTimer += delta; } else if (isPerformingRightAction) { rightActionTimer += delta; if (rightActionTimer > rightweapon.attacktime) { rightActionTimer = 0; isPerformingRightAction = false; rightweapon.onAttackEnd(); } } if (!isPerformingLeftAction && input.isLeftHandPressed()) { leftweapon.onAttackStart(); isPerformingLeftAction = true; leftActionTimer += delta; } else if (isPerformingLeftAction) { leftActionTimer += delta; if (leftActionTimer > leftweapon.attacktime) { leftActionTimer = 0; isPerformingLeftAction = false; rightweapon.onAttackEnd(); } } Vector3 movement = new Vector3(); Vector3 back = new Vector3(c.direction.x, c.direction.y, 0).nor(); back.nor(); movement.add(back.cpy().scl(input.getForward())); movement.add(back.cpy().crs(0, 0, 1).scl(input.getRight())); movement.nor(); movement.scl(input.isSprintPressed() ? 5 : 1); characterController.setWalkDirection(movement.cpy().scl(delta * runspeed)); if (movement.len() != 0) { face = movement.cpy().scl(-1); if (characterController.canJump()) { animations.setAnimation("Walking", -1, 0.4f * movement.len() * runspeed, null); } } else { if (characterController.canJump()) { animations.setAnimation(null); } } mi.transform.set(ghostObject.getWorldTransform().translate(0, 0, -0.25f)); mi.transform.rotate(0, 0, -1, (float) Math.toDegrees(Math.atan2(face.x, face.y))); updateWeaponInstances(); animations.update(delta); }
/** * Handles mouse button input. * * @param deltaX * @param deltaY * @param button * @return */ protected boolean process(float deltaX, float deltaY, int button) { if (button == rotateButton) { tmpV1.set(screen.active().direction).crs(screen.active().up).y = 0f; screen.active().rotateAround(target, tmpV1.nor(), deltaY * rotateAngle); screen.active().rotateAround(target, Vector3.Y, deltaX * -rotateAngle); } else if (button == translateButton) { screen .active() .translate( tmpV1 .set(screen.active().direction) .crs(screen.active().up) .nor() .scl(-deltaX * translateUnits)); screen.active().translate(tmpV2.set(screen.active().up).scl(-deltaY * translateUnits)); if (translateTarget) target.add(tmpV1).add(tmpV2); } else if (button == interactButton) { /** * @TODO Make the interact button interact here. No zooming. zoom code. * screen.active().translate(tmpV1.set(screen.active().direction).scl(deltaY * * translateUnits)); */ } if (autoUpdate) screen.active().update(); return true; }
public void setEnvironmentLights(Array<BaseLight<?>> lights, Vector3 sunDirection) { environment = new Environment(); environment.add( (shadowLight = new DirectionalShadowLight( GameSettings.SHADOW_MAP_WIDTH, GameSettings.SHADOW_MAP_HEIGHT, GameSettings.SHADOW_VIEWPORT_WIDTH, GameSettings.SHADOW_VIEWPORT_HEIGHT, GameSettings.SHADOW_NEAR, GameSettings.SHADOW_FAR)) .set( GameSettings.SHADOW_INTENSITY, GameSettings.SHADOW_INTENSITY, GameSettings.SHADOW_INTENSITY, sunDirection.nor())); environment.shadowMap = shadowLight; float ambientLight = GameSettings.SCENE_AMBIENT_LIGHT; environment.set( new ColorAttribute( ColorAttribute.AmbientLight, ambientLight, ambientLight, ambientLight, 1)); for (BaseLight<?> light : lights) { environment.add(light); } }
public Projectile( Vector3 startingPosition, Vector3 direction, float msSpeed, btCollisionWorld world) { btCollisionShape sphere = new btSphereShape(0.5f); collisionObject = new btCollisionObject(); collisionObject.setCollisionShape(sphere); collisionObject.userData = this; world.addCollisionObject(collisionObject); position = new Vector3(startingPosition); /* acceleration = new Vector3(direction); acceleration.nor().scl(msSpeed);*/ velocity = new Vector3(direction); velocity.nor().scl(msSpeed); transform = new Matrix4(); transform.setTranslation(position); collisionObject.setWorldTransform(transform); }
@Override public void circle( float width, float height, float centerX, float centerY, float centerZ, float normalX, float normalY, float normalZ, int divisions, float angleFrom, float angleTo) { tempV1.set(normalX, normalY, normalZ).crs(0, 0, 1); tempV2.set(normalX, normalY, normalZ).crs(0, 1, 0); if (tempV2.len2() > tempV1.len2()) tempV1.set(tempV2); tempV2.set(tempV1.nor()).crs(normalX, normalY, normalZ).nor(); circle( width, height, centerX, centerY, centerZ, normalX, normalY, normalZ, tempV1.x, tempV1.y, tempV1.z, tempV2.x, tempV2.y, tempV2.z, divisions, angleFrom, angleTo); }
public static void calculateVerticesN( MD5Joints skeleton, float[] weights, float vertices[], float[] verts, int vstride, int wstride, BoundingBox bbox) { for (int vertexOffset = 2, k = 0; vertexOffset < vertices.length; vertexOffset += vstride) { float finalX = 0; float finalY = 0; float finalZ = 0; int weightOffset = (int) vertices[vertexOffset]; int weightCount = (int) vertices[vertexOffset + 1]; weightOffset = weightOffset * wstride; // get the bind pose normal bn.set(vertices[vertexOffset + 2], vertices[vertexOffset + 3], vertices[vertexOffset + 4]); /* * float bnx = vertices[vertexOffset+2]; float bny = vertices[vertexOffset+3]; float bnz = vertices[vertexOffset+4]; */ for (int j = 0; j < weightCount; j++) { int jointOffset = (int) weights[weightOffset++] << 3; float bias = weights[weightOffset++]; float vx = weights[weightOffset++]; float vy = weights[weightOffset++]; float vz = weights[weightOffset++]; // weightOffset += 3; // get the weight normal vn.set(weights[weightOffset++], weights[weightOffset++], weights[weightOffset++]); float qx = skeleton.joints[jointOffset + 4]; float qy = skeleton.joints[jointOffset + 5]; float qz = skeleton.joints[jointOffset + 6]; float qw = skeleton.joints[jointOffset + 7]; // add to the bind pose normal: quat.x = qx; quat.y = qy; quat.z = qz; quat.w = qw; quat.rotate(vn); vn.mul(bias); bn.add(vn); // bnx += vn.x; bny += vn.y; bnz += vn.z; float ix = -qx, iy = -qy, iz = -qz, iw = qw; float tw = -qx * vx - qy * vy - qz * vz; float tx = qw * vx + qy * vz - qz * vy; float ty = qw * vy + qz * vx - qx * vz; float tz = qw * vz + qx * vy - qy * vx; vx = tx * iw + tw * ix + ty * iz - tz * iy; vy = ty * iw + tw * iy + tz * ix - tx * iz; vz = tz * iw + tw * iz + tx * iy - ty * ix; finalX += (skeleton.joints[jointOffset + 1] + vx) * bias; finalY += (skeleton.joints[jointOffset + 2] + vy) * bias; finalZ += (skeleton.joints[jointOffset + 3] + vz) * bias; } bbox.ext(finalX, finalY, finalZ); verts[k++] = finalX; verts[k++] = finalY; verts[k++] = finalZ; k += 2; // normals bn.nor(); verts[k++] = bn.x; // bnx; verts[k++] = bn.y; // bny; verts[k++] = bn.z; // bnz; // For each weight of a vertex, transform the vertex normal by the inverse joint's orientation // quaternion of the weight. You now have the normal in joint's local space. // Then when calculating the final vertex positions, you will be able to do the same for the // normals, except you won't have to translate from the joint's position when converting from // joint's local space to object space. } }
public static void calculateNormalsBind( MD5Joints skeleton, float[] weights, float vertices[], short indices[], float verts[], int vstride, int wstride) { for (int vertexOffset = 2, k = 0; vertexOffset < vertices.length; vertexOffset += vstride) { float finalX = 0; float finalY = 0; float finalZ = 0; int weightOffset = (int) vertices[vertexOffset]; int weightCount = (int) vertices[vertexOffset + 1]; weightOffset = weightOffset * wstride; for (int j = 0; j < weightCount; j++) { int jointOffset = (int) weights[weightOffset++] << 3; float bias = weights[weightOffset++]; float vx = weights[weightOffset++]; float vy = weights[weightOffset++]; float vz = weights[weightOffset++]; weightOffset += 3; // skip normal float qx = skeleton.joints[jointOffset + 4]; float qy = skeleton.joints[jointOffset + 5]; float qz = skeleton.joints[jointOffset + 6]; float qw = skeleton.joints[jointOffset + 7]; float ix = -qx, iy = -qy, iz = -qz, iw = qw; float tw = -qx * vx - qy * vy - qz * vz; float tx = qw * vx + qy * vz - qz * vy; float ty = qw * vy + qz * vx - qx * vz; float tz = qw * vz + qx * vy - qy * vx; vx = tx * iw + tw * ix + ty * iz - tz * iy; vy = ty * iw + tw * iy + tz * ix - tx * iz; vz = tz * iw + tw * iz + tx * iy - ty * ix; finalX += (skeleton.joints[jointOffset + 1] + vx) * bias; finalY += (skeleton.joints[jointOffset + 2] + vy) * bias; finalZ += (skeleton.joints[jointOffset + 3] + vz) * bias; } verts[k++] = finalX; verts[k++] = finalY; verts[k++] = finalZ; k += 2; k += 3; } // compute normals in bind pose for (int i = 0; i < indices.length; i += 3) { // only doing this once so let's use data structures short i1 = indices[i]; short i2 = indices[i + 1]; short i3 = indices[i + 2]; int vo1 = i1 * 8; int vo2 = i2 * 8; int vo3 = i3 * 8; Vector3 v1 = new Vector3(verts[vo1], verts[vo1 + 1], verts[vo1 + 2]); Vector3 v2 = new Vector3(verts[vo2], verts[vo2 + 1], verts[vo2 + 2]); Vector3 v3 = new Vector3(verts[vo3], verts[vo3 + 1], verts[vo3 + 2]); // calculate face normal. Clockwise winding. Vector3 fn = calcNor(v1, v2, v3); // store them back in the mesh's vertex array. int ovo1 = i1 * 7; int ovo2 = i2 * 7; int ovo3 = i3 * 7; vertices[ovo1 + 4] += fn.x; vertices[ovo1 + 5] += fn.y; vertices[ovo1 + 6] += fn.z; vertices[ovo2 + 4] += fn.x; vertices[ovo2 + 5] += fn.y; vertices[ovo2 + 6] += fn.z; vertices[ovo3 + 4] += fn.x; vertices[ovo3 + 5] += fn.y; vertices[ovo3 + 6] += fn.z; } for (int i = 0; i < indices.length; i += 3) { short i1 = indices[i]; short i2 = indices[i + 1]; short i3 = indices[i + 2]; int ovo1 = i1 * 7; int ovo2 = i2 * 7; int ovo3 = i3 * 7; vn.set(vertices[ovo1 + 4], vertices[ovo1 + 5], vertices[ovo1 + 6]); vn.nor(); vertices[ovo1 + 4] = vn.x; vertices[ovo1 + 5] = vn.y; vertices[ovo1 + 6] = vn.z; vn.set(vertices[ovo2 + 4], vertices[ovo2 + 5], vertices[ovo2 + 6]); vn.nor(); vertices[ovo2 + 4] = vn.x; vertices[ovo2 + 5] = vn.y; vertices[ovo2 + 6] = vn.z; vn.set(vertices[ovo3 + 4], vertices[ovo3 + 5], vertices[ovo3 + 6]); vn.nor(); vertices[ovo3 + 4] = vn.x; vertices[ovo3 + 5] = vn.y; vertices[ovo3 + 6] = vn.z; } // calculate weight normals for (int vertexOffset = 2; vertexOffset < vertices.length; vertexOffset += vstride) { int weightOffset = (int) vertices[vertexOffset]; int weightCount = (int) vertices[vertexOffset + 1]; weightOffset = weightOffset * wstride; for (int j = 0; j < weightCount; j++) { int jointOffset = (int) weights[weightOffset++] << 3; // FIXME why aren't these used? // float bias = weights[weightOffset++]; // float vx = weights[weightOffset++]; // float vy = weights[weightOffset++]; // float vz = weights[weightOffset++]; float qx = skeleton.joints[jointOffset + 4]; float qy = skeleton.joints[jointOffset + 5]; float qz = skeleton.joints[jointOffset + 6]; float qw = skeleton.joints[jointOffset + 7]; float vnx = vertices[vertexOffset + 2]; float vny = vertices[vertexOffset + 3]; float vnz = vertices[vertexOffset + 4]; vn.set(vnx, vny, vnz); quat.x = qx; quat.y = qy; quat.z = qz; quat.w = qw; quat.invert(); quat.rotate(vn); weights[weightOffset++] += vn.x; weights[weightOffset++] += vn.y; weights[weightOffset++] += vn.z; } } // normalize weight normals for (int i = 0; i < weights.length; i += wstride) { vn.set(weights[i + 5], weights[i + 6], weights[i + 7]); vn.nor(); weights[i + 5] = vn.x; weights[i + 6] = vn.y; weights[i + 7] = vn.z; } }