/******************************************************************************* * Copyright 2015 See AUTHORS file. * <p/> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.mygdx.game.pathfinding; import com.badlogic.gdx.ai.pfa.Connection; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.Array; /** * A {@code Triangle} is a node of the {@code NavMeshGraph}. * * @author jsjolund */ public class Triangle { public int triIndex; public int meshPartIndex; public Vector3 a; public Vector3 b; public Vector3 c; public Vector3 centroid; public Array<Connection<Triangle>> connections; public Triangle(Vector3 a, Vector3 b, Vector3 c, int triIndex, int meshPartIndex) { this.a = a; this.b = b; this.c = c; this.triIndex = triIndex; this.meshPartIndex = meshPartIndex; this.centroid = new Vector3(a).add(b).add(c).scl(1f / 3f); this.connections = new Array<Connection<Triangle>>(); } @Override public String toString() { final StringBuffer sb = new StringBuffer("Triangle{"); sb.append("triIndex=").append(triIndex); sb.append(", meshPartIndex=").append(meshPartIndex); sb.append('}'); return sb.toString(); } public int getIndex() { return triIndex; } public Array<Connection<Triangle>> getConnections() { return connections; } /** * Calculates the angle in radians between a reference vector and the (plane) normal of the triangle. * * @param reference * @return */ public float getAngle(Vector3 reference) { float x = reference.x; float y = reference.y; float z = reference.z; Vector3 normal = reference; normal.set(a).sub(b).crs(b.x - c.x, b.y - c.y, b.z - c.z).nor(); float angle = (float) Math.acos(normal.dot(x, y, z) / (normal.len() * Math.sqrt(x * x + y * y + z * z))); reference.set(x, y, z); return angle; } /** * Calculates a random point in this triangle. * * @param out Output vector * @return Output for chaining */ public Vector3 getRandomPoint(Vector3 out) { final float sr1 = (float) Math.sqrt(MathUtils.random()); final float r2 = MathUtils.random(); final float k1 = 1 - sr1; final float k2 = sr1 * (1 - r2); final float k3 = sr1 * r2; out.x = k1 * a.x + k2 * b.x + k3 * c.x; out.y = k1 * a.y + k2 * b.y + k3 * c.y; out.z = k1 * a.z + k2 * b.z + k3 * c.z; return out; } /** * Calculates the area of the triangle. * * @return */ public float area() { final float abx = b.x - a.x; final float aby = b.y - a.y; final float abz = b.z - a.z; final float acx = c.x - a.x; final float acy = c.y - a.y; final float acz = c.z - a.z; final float r = aby * acz - abz * acy; final float s = abz * acx - abx * acz; final float t = abx * acy - aby * acx; return 0.5f * (float) Math.sqrt(r * r + s * s + t * t); } }