Package com.l2client.navigation

Source Code of com.l2client.navigation.Path

package com.l2client.navigation;

import java.util.ArrayList;

import com.jme3.math.Vector3f;
import com.l2client.navigation.Line2D.LINE_CLASSIFICATION;

/**
* NavigationPath is a collection of waypoints that define a movement path for
* an Actor. This object is ownded by an Actor and filled by
* NavigationMesh::BuildNavigationPath().
*
* Portions Copyright (C) Greg Snook, 2000
*
* @author TR
*
*/
public class Path {
  public class WayPoint{
    public Vector3f position;
    public int cell = -1;
    public int mesh = -1;
    WayPoint(InternalWayPoint internal){
      this.position = internal.Position.clone();
      this.cell = internal.Cell.id;
      this.mesh = internal.mesh.hashCode();
    }
  }
  class InternalWayPoint {
    public Vector3f Position = new Vector3f(); // 3D position of waypoint
    public Cell Cell; // The cell which owns the waypoint
    public NavMesh mesh; // the mesh the cell belongs to
//    boolean borderCell;

    @Override
    public String toString() {
      return "WAYPOINT: pos:" + Position.x + "/" + Position.z + " cell:"
          + Cell;
    }
  };

  private ArrayList<InternalWayPoint> m_WaypointList = new ArrayList<InternalWayPoint>();
  private ArrayList<WayPoint> publicList = null;
 
  void clear(){
    m_WaypointList.clear();
    if(publicList != null){
      publicList.clear();
      publicList = null;
    }
  }
 
  void copyReverseInReverseOrder(Path from){
    for(int i=from.m_WaypointList.size()-1;i>=0;i--)
      m_WaypointList.add(from.m_WaypointList.get(i));
  }

  // : Setup
  // ----------------------------------------------------------------------------------------
  //
  // Sets up a new path from StartPoint to EndPoint. It adds the StartPoint as
  // the first
  // waypoint in the list and waits for further calls to AddWayPoint and
  // EndPath to
  // complete the list
  //
  // -------------------------------------------------------------------------------------://
//  void Setup(NavMesh Parent, Vector3f StartPoint, Cell StartCell){//,
////  }
////      Vector3f EndPoint, Cell EndCell) {
//    m_WaypointList.clear();
//
////    m_Parent = Parent;
////    m_StartPoint.Position = StartPoint;
////    m_StartPoint.Cell = StartCell;
////    m_EndPoint.Position = EndPoint;
////    m_EndPoint.Cell = EndCell;
//    WAYPOINT start = new WAYPOINT();
//    start.Position.set(StartPoint);
//    start.Cell = StartCell;
//    start.mesh = Parent;
//
//    // setup the waypoint list with our start and end points
//    m_WaypointList.add(start);;
//  }
  void setup(Vector3f startPoint, Cell startCell, NavMesh mesh){
      m_WaypointList.clear();

      InternalWayPoint start = new InternalWayPoint();
      start.Position.set(startPoint);
      start.Cell = startCell;
      start.mesh = mesh;
      // setup the waypoint list with our start point
      m_WaypointList.add(start);
    }

  // : AddWayPoint
  // ----------------------------------------------------------------------------------------
  //
  // Adds a new waypoint to the end of the list
  //
  // -------------------------------------------------------------------------------------://
//  void AddWayPoint(Vector3f Point, Cell Cell, NavMesh mesh) {
//    WAYPOINT NewPoint = new WAYPOINT();
//
//    NewPoint.Position.set(Point);
//    NewPoint.Cell = Cell;
//    NewPoint.mesh = mesh;
//
//    m_WaypointList.add(NewPoint);
//  }
  void addWayPoint(Vector3f point, Cell cell, NavMesh mesh) {
    InternalWayPoint NewPoint = new InternalWayPoint();

    NewPoint.Position.set(point);
    NewPoint.Cell = cell;
    NewPoint.mesh = mesh;

    m_WaypointList.add(NewPoint);
  }

//  // : EndPath
//  // ----------------------------------------------------------------------------------------
//  //
//  // Caps the end of the waypoint list by adding our final destination point
//  //
//  // -------------------------------------------------------------------------------------://
//  void EndPath() {
//    // cap the waypoint path with the last endpoint
//    if(m_EndPoint != null)
//      m_WaypointList.add(m_EndPoint);
//  }

//  Mesh Parent() {
//    return (m_Parent);
//  }

//  public WAYPOINT StartPoint() {
//    return (m_WaypointList.get(0));
//  }
//
  InternalWayPoint internalEndPoint() {
    if(m_WaypointList.size() > 0)
      return (m_WaypointList.get(m_WaypointList.size()-1));
    return null;
  }

  public ArrayList<WayPoint> WaypointList() {
    if(publicList == null){
      publicList = new ArrayList<WayPoint>(m_WaypointList.size());
      for(InternalWayPoint p : m_WaypointList)
        publicList.add(new WayPoint(p));
    }
    return publicList;
  }

//  // : GetFurthestVisibleWayPoint
//  // ----------------------------------------------------------------------------------------
//  //
//  // Find the furthest visible waypoint from the VantagePoint provided. This
//  // is used to
//  // smooth out irregular paths.
//  //
//  // -------------------------------------------------------------------------------------://
//  public WAYPOINT GetFurthestVisibleWayPoint(WAYPOINT VantagePoint) {
//    // see if we are already talking about the last waypoint
//    if (VantagePoint == m_WaypointList.get(m_WaypointList.size() - 1)) {
//      return (VantagePoint);
//    }
//    WAYPOINT Vantage = VantagePoint;
//    int i = m_WaypointList.indexOf(VantagePoint);
//    if(i < 0)
//      return VantagePoint;
////    System.out.print("WAY IND:" + i);
//
//    WAYPOINT TestWaypoint = VantagePoint;
//    TestWaypoint = m_WaypointList.get(++i);
//
//    if (TestWaypoint == m_WaypointList.get(m_WaypointList.size() - 1)) {
////      System.out.println(" WAY IND was last");
//      return (TestWaypoint);
//    }
//
//    WAYPOINT VisibleWaypoint = TestWaypoint;
//    // TestWaypoint = m_WaypointList.get(++i);
//
//    while (TestWaypoint != m_WaypointList.get(m_WaypointList.size() - 1)) {
//      WAYPOINT Test = TestWaypoint;
//      if (!Vantage.mesh.LineOfSightTest(Vantage.Cell, Vantage.Position,
//          Test.Position)) {
////        System.out.println(" WAY IND was:" + i);
//        return (VisibleWaypoint);
//      }
//      VisibleWaypoint = TestWaypoint;
//      TestWaypoint = m_WaypointList.get(++i);
//    }
////    System.out.println(" WAY IND was:" + i);
//    // the last
//    return (TestWaypoint);
//  }
 
  void optimize(){
    int size = m_WaypointList.size();
   
    int current = 0;
    int next = 1;
    ArrayList<InternalWayPoint> newList = new ArrayList<InternalWayPoint>();
    //add start to optimized one
    newList.add(m_WaypointList.get(0));
    //nothing to do onnly two points
    if(size <= 2) {
      return
    }
   
    size--;
    //try to optimize as long as we have not reached the last point
    while(next < size) {
      if(isEndVisible(current, next)){
        //go on to test the next point
        next++;
      } else {
        //if the last is not the start add the last one as the next waypoint as it was the last one visible
        if(next -1 != current) {
          newList.add(m_WaypointList.get(next - 1));
          //now go on with new current and next
          current = next -1;
          //next is already on the right spot
        } else {
          newList.add(m_WaypointList.get(next));
          current = next;//BOOOM something went wrong??!?!
          next = next+1;
        }
       
      }
    }
    //do we have the last one on it?
    if(m_WaypointList.get(size) != newList.get(newList.size()-1))
      newList.add(m_WaypointList.get(size));
   
    m_WaypointList.clear();
    m_WaypointList = newList;     
  }
 
  private boolean isEndVisible(int from, int to){
    //is start at the end or even further?
    if(from>=to)
      return false;
    //out of bounds?
    if(from <0 || to > m_WaypointList.size())
      return false;
   
    InternalWayPoint wFrom = m_WaypointList.get(from);
    InternalWayPoint wTo = m_WaypointList.get(to);
   
    //early out if both are on the same cell (line will end on border or not even getting to the border at all)
    if(wFrom.Cell == wTo.Cell)
      return true;
   
    Line2D wayLine = new Line2D(wFrom.Position.x, wFrom.Position.z,wTo.Position.x, wTo.Position.z);
   
    InternalWayPoint check = null;
    for(int i = from+1;i<=to;i++){
      check = m_WaypointList.get(i);
      int wall = check.Cell.ArrivalWall();
      Line2D wallLine = check.Cell.m_Side[wall];
      LINE_CLASSIFICATION result = wallLine.Intersection(wayLine, null);
      if(Line2D.LINE_CLASSIFICATION.SEGMENTS_INTERSECT != result && LINE_CLASSIFICATION.B_BISECTS_A != result){
//System.out.println("Optimization between "+from+" and "+ i+" result:"+result);
        return false;
      }
    }
   
    return true;
  }
 
  @Override
  public String toString() {
    StringBuilder b = new StringBuilder();
    b.append("-- WAYPOINT LIST --\n");
    for(InternalWayPoint p :m_WaypointList)
      b.append(p.toString()).append("\n");

    return b.toString();
  }
 
}
TOP

Related Classes of com.l2client.navigation.Path

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.