protected override Vector3 UpdateTarget (RichFunnel fn) { Matrix4x4 m = graph.GetMatrix (); Matrix4x4 mi = m.inverse; Debug.DrawRay (m.MultiplyPoint3x4 (tr.position), Vector3.up*2, Color.red); Debug.DrawRay (mi.MultiplyPoint3x4 (tr.position), Vector3.up*2, Color.green); buffer.Clear (); /* Current position. We read and write to tr.position as few times as possible since doing so * is much slower than to read and write from/to a local variable */ Vector3 position = tr.position; bool requiresRepath; // Update, but first convert our position to graph space, then convert the result back to world space var positionInGraphSpace = m.MultiplyPoint3x4 (position); positionInGraphSpace = fn.Update (positionInGraphSpace, buffer, 2, out lastCorner, out requiresRepath); position = mi.MultiplyPoint3x4 (positionInGraphSpace); Debug.DrawRay ( position, Vector3.up*3, Color.black ); // convert the result to world space from graph space for ( int i=0; i < buffer.Count; i++ ) { buffer[i] = mi.MultiplyPoint3x4 ( buffer[i] ); Debug.DrawRay ( buffer[i], Vector3.up*3, Color.yellow ); } if (requiresRepath && !waitingForPathCalc) { UpdatePath (); } return position; }
/** Use this for initialization. * * \param s Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\ * \param p Path to follow * \param mergePartEndpoints If true, then adjacent parts that the path is split up in will * try to use the same start/end points. For example when using a link on a navmesh graph * Instead of first following the path to the center of the node where the link is and then * follow the link, the path will be adjusted to go to the exact point where the link starts * which usually makes more sense. * \param simplificationMode The path can optionally be simplified. This can be a bit expensive for long paths. */ public void Initialize (Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode) { if (p.error) throw new System.ArgumentException ("Path has an error"); List<GraphNode> nodes = p.path; if (nodes.Count == 0) throw new System.ArgumentException ("Path traverses no nodes"); seeker = s; // Release objects back to object pool // Yeah, I know, it's casting... but this won't be called much for (int i=0;i<parts.Count;i++) { if (parts[i] is RichFunnel) ObjectPool<RichFunnel>.Release (parts[i] as RichFunnel); else if (parts[i] is RichSpecial) ObjectPool<RichSpecial>.Release (parts[i] as RichSpecial); } parts.Clear(); currentPart = 0; // Initialize new //Break path into parts for (int i=0;i<nodes.Count;i++) { if (nodes[i] is TriangleMeshNode) { var funnelGraph = AstarData.GetGraph (nodes[i]) as IFunnelGraph; RichFunnel f = ObjectPool<RichFunnel>.Claim ().Initialize (this, funnelGraph); f.funnelSimplificationMode = simplificationMode; int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node) ) { break; } } i--; if (sIndex == 0) { f.exactStart = p.vectorPath[0]; } else { f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex-1 : sIndex].position; } if (i == nodes.Count-1) { f.exactEnd = p.vectorPath[p.vectorPath.Count-1]; } else { f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i+1 : i].position; } f.BuildFunnelCorridor (nodes, sIndex, i); parts.Add (f); } else if (NodeLink2.GetNodeLink(nodes[i]) != null) { NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]); int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (i++; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex) { break; } } i--; if (i - sIndex > 1) { throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex)); } else if (i - sIndex == 0) { //Just continue, it might be the case that a NodeLink was the closest node continue; } RichSpecial rps = ObjectPool<RichSpecial>.Claim().Initialize (nl, nodes[sIndex]); parts.Add(rps); } } }
protected virtual Vector3 UpdateTarget ( RichFunnel fn ) { buffer.Clear (); /* Current position. We read and write to tr.position as few times as possible since doing so * is much slower than to read and write from/to a local variable */ Vector3 position = tr.position; bool requiresRepath; position = fn.Update (position, buffer, 2, out lastCorner, out requiresRepath); if (requiresRepath && !waitingForPathCalc) { UpdatePath (); } return position; }