/** Query the texture for the colour at the given intersection (in 3D space). */ private Colour queryTexture(Vector3 intersection) { Vector3 Vn = mNorth; Vector3 Ve = Vector3.pool.borrow().reset(Vn.y, -Vn.x, 0.0); // (AKA Vn.cross(0, 0, 1)) Vector3 Vp = Vector3.pool.borrow().reset(intersection); Vp.subtract(mPlanetOrigin); Ve.normalize(); Vp.normalize(); double phi = Math.acos(-1.0 * Vector3.dot(Vn, Vp)); double v = phi / Math.PI; double theta = (Math.acos(Vector3.dot(Vp, Ve) / Math.sin(phi))) / (Math.PI * 2.0); double u; Vector3 c = Vector3.cross(Vn, Ve); if (Vector3.dot(c, Vp) > 0) { u = theta; } else { u = 1.0 - theta; } Vector3.pool.release(c); Vector3.pool.release(Ve); Vector3.pool.release(Vp); return mTexture.getTexel(u, v); }
/** * Sets the minimum and maximum vector to positive and negative infinity. * * @return This bounding box for chaining. */ public Bounds inf() { min.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); max.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); cnt.set(0, 0, 0); dim.set(0, 0, 0); return this; }
/** * Definiert die Plane über einen Punkt und eine Normake * * @param distance Die Distantz zum Koordinatenursprung * @param normal Die Normale * @return Diese Instanz für method chaining */ @NotNull public Plane3 set(@NotNull final Vector3 normal, final float distance) { assert !normal.isEmpty(); _normal.set(normal.getNormalized()); _distanceToOrigin = -distance; return this; }
// Fatory Methods public static Matrix3 rotation(Vector3 axis, final float angle) { if (angle == 0) return Identity; axis = axis.unit(); if (!axis.isFinite()) throw new RuntimeException(); final float c = GMath.cos(angle), s = GMath.sin(angle); return axis.mul(1 - c).mul(axis).add(Identity, c).add(axis.mul(s).tilda()); }
/** * Bezieht einen Strahl, der in die entgegengesetzte Richtung zeigt * * @return Der Strahl */ @NotNull @ReturnsCachedValue public Ray3 getInverted() { Vector3 inverted = direction.getInverted(); Ray3 ray = Ray3.createNew(origin, inverted); inverted.recycle(); return ray; }
/** * Calculates diffuse lighting at the given point with the given normal. * * @param normal Normal at the point we're calculating diffuse lighting for. * @param point The point at which we're calculating diffuse lighting. * @return The diffuse factor of lighting. */ private double diffuse(Vector3 normal, Vector3 point) { Vector3 directionToLight = Vector3.pool.borrow().reset(mSunOrigin); directionToLight.subtract(point); directionToLight.normalize(); double factor = Vector3.dot(normal, directionToLight); Vector3.pool.release(directionToLight); return factor; }
public void rotate(Vector3 v) { double ts = -this.x * v.x - this.y * v.y - this.z * v.z; double tx = this.s * v.x + this.y * v.z - this.z * v.y; double ty = this.s * v.y - this.x * v.z + this.z * v.x; double tz = this.s * v.z + this.x * v.y - this.y * v.x; v.x = (tx * this.s - ts * this.x - ty * this.z + tz * this.y); v.y = (ty * this.s - ts * this.y + tx * this.z - tz * this.x); v.z = (tz * this.s - ts * this.z - tx * this.y + ty * this.x); }
/** * Definiert die Plane über einen Punkt und eine Normake * * @param center Der Punkt * @param normal Die Normale * @return Diese Instanz für method chaining */ @NotNull public Plane3 set(@NotNull final Vector3 normal, @NotNull final Vector3 center) { assert !normal.isEmpty(); // Normale setzen _normal.set(normal.getNormalized()); // Entfernung berechnen _distanceToOrigin = normal.dotWithInversion(center); return this; }
/** * Berechnet die Distanz eines Punktes zu diesem Strahl * * @param point Der Punkt * @return Die berechnete Distanz */ public float getDistanceFromPoint(@NotNull final Vector3 point) { // http://answers.yahoo.com/question/index?qid=20080912194015AAIlm9X Vector3 w = point.sub(origin).crossInPlace(direction); float length = w.getLength(); // aufräumen und raus hier w.recycle(); return length; }
public Raycaster pickingRay(Vector3 vector, Camera camera) { vector.z = -1.0f; Vector3 end = new Vector3(vector.x, vector.y, 1.0f); unprojectVector(vector, camera); unprojectVector(end, camera); end.sub(vector).normalize(); return new Raycaster(vector, end); }
/** * Create a new Twist with the given linear and angular values. * * @param linear The linear value of the twist. * @param angular The angular value of the twist. */ public Twist(Vector3 linear, Vector3 angular) { // build the JSON object super( Json.createObjectBuilder() .add(Twist.FIELD_LINEAR, linear.toJsonObject()) .add(Twist.FIELD_ANGULAR, angular.toJsonObject()) .build(), Twist.TYPE); this.linear = linear; this.angular = angular; }
/** * Extends this bounding box by the given sphere. * * @param center Sphere center * @param radius Sphere radius * @return This bounding box for chaining. */ public Bounds ext(Vector3 center, double radius) { return this.set( min.set( min(min.x, center.x - radius), min(min.y, center.y - radius), min(min.z, center.z - radius)), max.set( max(max.x, center.x + radius), max(max.y, center.y + radius), max(max.z, center.z + radius))); }
/** * Calculates light intensity from the sun. * * @param intersection Point where the ray we're currently tracing intersects with the planet. */ private double lightSphere(Vector3 intersection) { Vector3 surfaceNormal = Vector3.pool.borrow().reset(intersection); surfaceNormal.subtract(mPlanetOrigin); surfaceNormal.normalize(); double intensity = diffuse(surfaceNormal, intersection); intensity = Math.max(mAmbient, Math.min(1.0, intensity)); Vector3.pool.release(surfaceNormal); return intensity; }
/** * Vektor reflektion Vnew = - v + ( 2 * v * n) * n * * @param n Normale */ public Vector3 reflectedOn(Normal3 n) { Vector3 resVector = this; double skalar = resVector.dot(n) * 2; Normal3 normale = n.mul(skalar); resVector = resVector.mul(-1.0); resVector = resVector.add(normale); return resVector; }
/** * Create a new Twist based on the given JSON object. Any missing values will be set to their * defaults. * * @param jsonObject The JSON object to parse. * @return A Twist message based on the given JSON object. */ public static Twist fromJsonObject(JsonObject jsonObject) { // check the fields Vector3 linear = jsonObject.containsKey(Twist.FIELD_LINEAR) ? Vector3.fromJsonObject(jsonObject.getJsonObject(Twist.FIELD_LINEAR)) : new Vector3(); Vector3 angular = jsonObject.containsKey(Twist.FIELD_ANGULAR) ? Vector3.fromJsonObject(jsonObject.getJsonObject(Twist.FIELD_ANGULAR)) : new Vector3(); return new Twist(linear, angular); }
/** * Sets the given minimum and maximum vector. * * @param minimum The minimum vector * @param maximum The maximum vector * @return This bounding box for chaining. */ public Bounds set(Vector3 minimum, Vector3 maximum) { min.set( minimum.x < maximum.x ? minimum.x : maximum.x, minimum.y < maximum.y ? minimum.y : maximum.y, minimum.z < maximum.z ? minimum.z : maximum.z); max.set( minimum.x > maximum.x ? minimum.x : maximum.x, minimum.y > maximum.y ? minimum.y : maximum.y, minimum.z > maximum.z ? minimum.z : maximum.z); cnt.set(min).add(max).scl(0.5f); dim.set(max).sub(min); return this; }
/** * Projiziert einen Punkt auf den Strahl * * @param point Der Punkt * @return Der projizierte Punkt */ @NotNull @ReturnsCachedValue public Vector3 projectPoint(@NotNull final Vector3 point) { // Richtung bestimmen und auf Richtungsvektor projizieren Vector3 w = point.sub(origin); Vector3 projected = direction.mul( w.dot( direction)); // TODO: Als static herausziehen, damit für diesen Test das Caching der // anderen Werte nicht nötig ist w.recycle(); return projected; }
@Override // from IBox public Vector3 vertex(int code, Vector3 result) { return result.set( ((code & (1 << 2)) == 0) ? _minExtent.x : _maxExtent.x, ((code & (1 << 1)) == 0) ? _minExtent.y : _maxExtent.y, ((code & (1 << 0)) == 0) ? _minExtent.z : _maxExtent.z); }
@Override // from IBox public boolean intersection(IRay3 ray, Vector3 result) { IVector3 origin = ray.origin(); if (contains(origin)) { result.set(origin); return true; } IVector3 dir = ray.direction(); double t = Float.MAX_VALUE; if (Math.abs(dir.x()) > MathUtil.EPSILON) { t = Math.min(t, intersectionX(ray, _minExtent.x)); t = Math.min(t, intersectionX(ray, _maxExtent.x)); } if (Math.abs(dir.y()) > MathUtil.EPSILON) { t = Math.min(t, intersectionY(ray, _minExtent.y)); t = Math.min(t, intersectionY(ray, _maxExtent.y)); } if (Math.abs(dir.z()) > MathUtil.EPSILON) { t = Math.min(t, intersectionZ(ray, _minExtent.z)); t = Math.min(t, intersectionZ(ray, _maxExtent.z)); } if (t == Float.MAX_VALUE) { return false; } origin.addScaled(dir, t, result); return true; }
public Box3 setFromCenterAndSize(Vector3 center, Vector3 size) { Vector3 halfSize = _v1.copy(size).multiply(0.5); this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; }
public Vector3 getDirection() { Matrix.setIdentityM(matrix, 0); Matrix.rotateM(matrix, 0, yaw, 0, 1, 0); Matrix.rotateM(matrix, 0, pitch, 1, 0, 0); Matrix.multiplyMV(outVex, 0, matrix, 0, inVex, 0); direction.set(outVex[0], outVex[1], outVex[2]); return direction; }
protected String getResponse(HttpServletRequest request) { boolean handledData = false; String debugType = Common.getRequestString(request, "debug_type", ""); if (debugType.equals("terrain")) { System.out.println("Debug data: terrain"); String data = Common.getRequestString(request, "data", ""); int height = Common.getRequestInt(request, "height", 0); int width = Common.getRequestInt(request, "width", 0); Gson gson = new Gson(); Vector3[] terrainData = gson.fromJson(data, Vector3[].class); Vector3 vertex; for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { vertex = terrainData[(h * height) + w]; // System.out.println("X: " + vertex.getX() + " Y: " + vertex.getY() + " Z: " + // vertex.getZ()); if (vertex.getY() != 0.0) { System.out.print("0"); } else { System.out.print("X"); } } System.out.println(); } handledData = true; } if (handledData) { return "ok"; } else { return "nothing to do"; } }
public PlanetRenderer(Template.PlanetTemplate tmpl, Random rand) { mPlanetOrigin = Vector3.pool.borrow().reset(0.0, 0.0, 30.0); mTexture = new TextureGenerator(tmpl.getParameter(Template.TextureTemplate.class), rand); mSunOrigin = tmpl.getSunLocation(); mAmbient = tmpl.getAmbient(); mPlanetRadius = tmpl.getPlanetSize(); List<Template.AtmosphereTemplate> atmosphereTemplates = tmpl.getParameters(Template.AtmosphereTemplate.class); if (atmosphereTemplates != null && atmosphereTemplates.size() > 0) { mAtmospheres = new ArrayList<Atmosphere>(); for (Template.AtmosphereTemplate atmosphereTemplate : atmosphereTemplates) { mAtmospheres.add(new Atmosphere(atmosphereTemplate, rand)); } } mNorth = Vector3.pool.borrow().reset(tmpl.getNorthFrom()); Vector3.interpolate(mNorth, tmpl.getNorthTo(), rand.nextDouble()); mNorth.normalize(); }
/** * Liefert den Punkt mit dem angegebenen Index * * @param point Der Punkt * @return Der Punkt (cached) */ @ReturnsCachedValue @NotNull public final Vector3 getCornerPoint(@NotNull final BoxPoint point) { assert extent.x >= 0; assert extent.y >= 0; assert extent.z >= 0; final int id = point.pointId; return Vector3.createNew( ((id & 1) == 0) ? (center.x - extent.x) : (center.x + extent.x), ((id & 2) == 0) ? (center.y - extent.y) : (center.y + extent.y), ((id & 4) == 0) ? (center.z + extent.z) : (center.z - extent.z) // NOTE: OpenGL macht's andersrum! ); }
/** * Traces a ray along the given direction. We assume the origin is (0,0,0) (i.e. the eye). * * @param direction The direction of the ray we're going to trace. * @return A \c Vector3 representing the point in space where we intersect with the planet, or \c * null if there's no intersection. */ private Vector3 raytrace(Vector3 direction) { // intersection of a sphere and a line final double a = Vector3.dot(direction, direction); Vector3 blah = Vector3.pool.borrow().reset(mPlanetOrigin); blah.scale(-1); final double b = 2.0 * Vector3.dot(direction, blah); Vector3.pool.release(blah); final double c = Vector3.dot(mPlanetOrigin, mPlanetOrigin) - (mPlanetRadius * mPlanetRadius); final double d = (b * b) - (4.0 * a * c); if (d > 0.0) { double sign = (c < -0.00001) ? 1.0 : -1.0; double distance = (-b + (sign * Math.sqrt(d))) / (2.0 * a); Vector3 intersection = Vector3.pool.borrow().reset(direction); intersection.scale(distance); return intersection; } else { return null; } }
/** 36 mul, 1 div */ public Matrix3 inv() { final float d = 1 / det(); final Vector3 p = new Vector3(b.y * c.z - b.z * c.y, c.y * a.z - a.y * c.z, a.y * b.z - b.y * a.z, d); if (!p.isFinite()) return Matrix3.Zero; final Vector3 q = new Vector3(b.z * c.x - b.x * c.z, a.x * c.z - c.x * a.z, b.x * a.z - a.x * b.z, d); if (!q.isFinite()) return Matrix3.Zero; final Vector3 r = new Vector3(b.x * c.y - c.x * b.y, c.x * a.y - a.x * c.y, a.x * b.y - a.y * b.x, d); if (!r.isFinite()) return Matrix3.Zero; return new Matrix3(p, q, r); }
/** * Ermittelt die Distanz eines Punktes zur Ebene * * @param point Der Punkt * @return Die Distanz zur Ebene */ public float getDistanceFromPoint(@NotNull final Vector3 point) { final float d1 = _normal.dot(point); return d1 + _distanceToOrigin; }
/** * Definiert die Plane über drei Punkte. * * @param a Erster Punkt * @param b Zweiter Punkt * @param c Dritter Punkt * @return Diese Instanz für method chaining */ @NotNull public Plane3 set(@NotNull final Vector3 a, @NotNull final Vector3 b, @NotNull final Vector3 c) { assert !a.equals(b) && !b.equals(c); // TODO: Dürfen nicht auf einer Geraden liegen! // Normale berechnen: _normal = a.sub(b).cross(a.sub(c)); final Vector3 aSubB = a.sub(b); Vector3 aSubC = a.sub(c); _normal.set(aSubB.cross(aSubC)); _normal.normalize(); // aSubB freigeben. // aSubC wird noch nicht freigegeben, da wir den Wert in Kürze weiterverwenden werden aSubB.recycle(); // Entfernung berechnen final Vector3 invNormal = aSubC; invNormal.set(_normal).invert(); _distanceToOrigin = invNormal.dot(a); invNormal.recycle(); return this; }
/** * Erzeugt eine Plane über ihren Mittelpunkt und ihre Normale * * @param center Mittelpunkt * @param normal Normale */ private Plane3(@NotNull final Vector3 center, @NotNull final Vector3 normal) { assert !normal.isEmpty(); set(center, normal); }
/** * Liefert die Position dieser Plane * * @return Die Referenz auf die Positionskomponente * @see #getDistanceFromOrigin() */ @NotNull @ReturnsCachedValue public Vector3 getCenter() { return _normal.mul(_distanceToOrigin); }