public class dtCrowd {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public dtCrowd() {
        swigCPtr = RecastJNI.dtAllocCrowd();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }
    
    public dtCrowd(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(dtCrowd obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.dtFreeCrowd(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    public boolean init(int maxAgents, float maxAgentRadius, NavMesh nav) {
        return RecastJNI.dtCrowd_init(swigCPtr, this, maxAgents, maxAgentRadius, NavMesh.getCPtr(nav), nav);
    }

    public void setObstacleAvoidanceParams(int idx, dtObstacleAvoidanceParams params) {
        RecastJNI.dtCrowd_setObstacleAvoidanceParams(swigCPtr, this, idx, dtObstacleAvoidanceParams.getCPtr(params), params);
    }

    public dtObstacleAvoidanceParams getObstacleAvoidanceParams(int idx) {
        long cPtr = RecastJNI.dtCrowd_getObstacleAvoidanceParams(swigCPtr, this, idx);
        return (cPtr == 0) ? null : new dtObstacleAvoidanceParams(cPtr, false);
    }

    public dtCrowdAgent getAgent(int idx) {
        long cPtr = RecastJNI.dtCrowd_getAgent(swigCPtr, this, idx);
        return (cPtr == 0) ? null : new dtCrowdAgent(cPtr, false);
    }

    public dtCrowdAgent getEditableAgent(int idx) {
        long cPtr = RecastJNI.dtCrowd_getEditableAgent(swigCPtr, this, idx);
        return (cPtr == 0) ? null : new dtCrowdAgent(cPtr, false);
    }

    public int getAgentCount() {
        return RecastJNI.dtCrowd_getAgentCount(swigCPtr, this);
    }

    public int addAgent(SWIGTYPE_p_float pos, dtCrowdAgentParams params) {
        return RecastJNI.dtCrowd_addAgent(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), dtCrowdAgentParams.getCPtr(params), params);
    }

    public void updateAgentParameters(int idx, dtCrowdAgentParams params) {
        RecastJNI.dtCrowd_updateAgentParameters(swigCPtr, this, idx, dtCrowdAgentParams.getCPtr(params), params);
    }

    public void removeAgent(int idx) {
        RecastJNI.dtCrowd_removeAgent(swigCPtr, this, idx);
    }

    public boolean requestMoveTarget(int idx, long ref, SWIGTYPE_p_float pos) {
        return RecastJNI.dtCrowd_requestMoveTarget(swigCPtr, this, idx, ref, SWIGTYPE_p_float.getCPtr(pos));
    }

    public boolean requestMoveVelocity(int idx, SWIGTYPE_p_float vel) {
        return RecastJNI.dtCrowd_requestMoveVelocity(swigCPtr, this, idx, SWIGTYPE_p_float.getCPtr(vel));
    }

    public boolean resetMoveTarget(int idx) {
        return RecastJNI.dtCrowd_resetMoveTarget(swigCPtr, this, idx);
    }

    public int getActiveAgents(SWIGTYPE_p_p_dtCrowdAgent agents, int maxAgents) {
        return RecastJNI.dtCrowd_getActiveAgents(swigCPtr, this, SWIGTYPE_p_p_dtCrowdAgent.getCPtr(agents), maxAgents);
    }

    public void update(float dt, dtCrowdAgentDebugInfo debug) {
        RecastJNI.dtCrowd_update(swigCPtr, this, dt, dtCrowdAgentDebugInfo.getCPtr(debug), debug);
    }

    public QueryFilter getFilter(int i) {
        long cPtr = RecastJNI.dtCrowd_getFilter(swigCPtr, this, i);
        return (cPtr == 0) ? null : new QueryFilter(cPtr, false);
    }

    public QueryFilter getEditableFilter(int i) {
        long cPtr = RecastJNI.dtCrowd_getEditableFilter(swigCPtr, this, i);
        return (cPtr == 0) ? null : new QueryFilter(cPtr, false);
    }

    public SWIGTYPE_p_float getQueryExtents() {
        long cPtr = RecastJNI.dtCrowd_getQueryExtents(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public int getVelocitySampleCount() {
        return RecastJNI.dtCrowd_getVelocitySampleCount(swigCPtr, this);
    }

    public dtProximityGrid getGrid() {
        long cPtr = RecastJNI.dtCrowd_getGrid(swigCPtr, this);
        return (cPtr == 0) ? null : new dtProximityGrid(cPtr, false);
    }

    public dtPathQueue getPathQueue() {
        long cPtr = RecastJNI.dtCrowd_getPathQueue(swigCPtr, this);
        return (cPtr == 0) ? null : new dtPathQueue(cPtr, false);
    }

    public NavMeshQuery getNavMeshQuery() {
        long cPtr = RecastJNI.dtCrowd_getNavMeshQuery(swigCPtr, this);
        return (cPtr == 0) ? null : new NavMeshQuery(cPtr, false);
    }
} public class dtCrowdAgent {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public dtCrowdAgent(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(dtCrowdAgent obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtCrowdAgent(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setActive(boolean value) {
        RecastJNI.dtCrowdAgent_active_set(swigCPtr, this, value);
    }

    public boolean getActive() {
        return RecastJNI.dtCrowdAgent_active_get(swigCPtr, this);
    }

    public void setState(short value) {
        RecastJNI.dtCrowdAgent_state_set(swigCPtr, this, value);
    }

    public short getState() {
        return RecastJNI.dtCrowdAgent_state_get(swigCPtr, this);
    }

    public void setPartial(boolean value) {
        RecastJNI.dtCrowdAgent_partial_set(swigCPtr, this, value);
    }

    public boolean getPartial() {
        return RecastJNI.dtCrowdAgent_partial_get(swigCPtr, this);
    }

    public void setCorridor(PathCorridor value) {
        RecastJNI.dtCrowdAgent_corridor_set(swigCPtr, this, PathCorridor.getCPtr(value), value);
    }

    public PathCorridor getCorridor() {
        long cPtr = RecastJNI.dtCrowdAgent_corridor_get(swigCPtr, this);
        return (cPtr == 0) ? null : new PathCorridor(cPtr, false);
    }

    public void setBoundary(dtLocalBoundary value) {
        RecastJNI.dtCrowdAgent_boundary_set(swigCPtr, this, dtLocalBoundary.getCPtr(value), value);
    }

    public dtLocalBoundary getBoundary() {
        long cPtr = RecastJNI.dtCrowdAgent_boundary_get(swigCPtr, this);
        return (cPtr == 0) ? null : new dtLocalBoundary(cPtr, false);
    }

    public void setTopologyOptTime(float value) {
        RecastJNI.dtCrowdAgent_topologyOptTime_set(swigCPtr, this, value);
    }

    public float getTopologyOptTime() {
        return RecastJNI.dtCrowdAgent_topologyOptTime_get(swigCPtr, this);
    }

    public void setNeis(dtCrowdNeighbour value) {
        RecastJNI.dtCrowdAgent_neis_set(swigCPtr, this, dtCrowdNeighbour.getCPtr(value), value);
    }

    public dtCrowdNeighbour getNeis() {
        long cPtr = RecastJNI.dtCrowdAgent_neis_get(swigCPtr, this);
        return (cPtr == 0) ? null : new dtCrowdNeighbour(cPtr, false);
    }

    public void setNneis(int value) {
        RecastJNI.dtCrowdAgent_nneis_set(swigCPtr, this, value);
    }

    public int getNneis() {
        return RecastJNI.dtCrowdAgent_nneis_get(swigCPtr, this);
    }

    public void setDesiredSpeed(float value) {
        RecastJNI.dtCrowdAgent_desiredSpeed_set(swigCPtr, this, value);
    }

    public float getDesiredSpeed() {
        return RecastJNI.dtCrowdAgent_desiredSpeed_get(swigCPtr, this);
    }

    public void setNpos(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_npos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getNpos() {
        long cPtr = RecastJNI.dtCrowdAgent_npos_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setDisp(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_disp_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getDisp() {
        long cPtr = RecastJNI.dtCrowdAgent_disp_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setDvel(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_dvel_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getDvel() {
        long cPtr = RecastJNI.dtCrowdAgent_dvel_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setNvel(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_nvel_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getNvel() {
        long cPtr = RecastJNI.dtCrowdAgent_nvel_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setVel(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_vel_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getVel() {
        long cPtr = RecastJNI.dtCrowdAgent_vel_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setParams(dtCrowdAgentParams value) {
        RecastJNI.dtCrowdAgent_params_set(swigCPtr, this, dtCrowdAgentParams.getCPtr(value), value);
    }

    public dtCrowdAgentParams getParams() {
        long cPtr = RecastJNI.dtCrowdAgent_params_get(swigCPtr, this);
        return (cPtr == 0) ? null : new dtCrowdAgentParams(cPtr, false);
    }

    public void setCornerVerts(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_cornerVerts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getCornerVerts() {
        long cPtr = RecastJNI.dtCrowdAgent_cornerVerts_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setCornerFlags(SWIGTYPE_p_unsigned_char value) {
        RecastJNI.dtCrowdAgent_cornerFlags_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public SWIGTYPE_p_unsigned_char getCornerFlags() {
        long cPtr = RecastJNI.dtCrowdAgent_cornerFlags_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
    }

    public void setCornerPolys(SWIGTYPE_p_unsigned_int value) {
        RecastJNI.dtCrowdAgent_cornerPolys_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    public SWIGTYPE_p_unsigned_int getCornerPolys() {
        long cPtr = RecastJNI.dtCrowdAgent_cornerPolys_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_int(cPtr, false);
    }

    public void setNcorners(int value) {
        RecastJNI.dtCrowdAgent_ncorners_set(swigCPtr, this, value);
    }

    public int getNcorners() {
        return RecastJNI.dtCrowdAgent_ncorners_get(swigCPtr, this);
    }

    public void setTargetState(short value) {
        RecastJNI.dtCrowdAgent_targetState_set(swigCPtr, this, value);
    }

    public short getTargetState() {
        return RecastJNI.dtCrowdAgent_targetState_get(swigCPtr, this);
    }

    public void setTargetRef(long value) {
        RecastJNI.dtCrowdAgent_targetRef_set(swigCPtr, this, value);
    }

    public long getTargetRef() {
        return RecastJNI.dtCrowdAgent_targetRef_get(swigCPtr, this);
    }

    public void setTargetPos(SWIGTYPE_p_float value) {
        RecastJNI.dtCrowdAgent_targetPos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public SWIGTYPE_p_float getTargetPos() {
        long cPtr = RecastJNI.dtCrowdAgent_targetPos_get(swigCPtr, this);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public void setTargetPathqRef(long value) {
        RecastJNI.dtCrowdAgent_targetPathqRef_set(swigCPtr, this, value);
    }

    public long getTargetPathqRef() {
        return RecastJNI.dtCrowdAgent_targetPathqRef_get(swigCPtr, this);
    }

    public void setTargetReplan(boolean value) {
        RecastJNI.dtCrowdAgent_targetReplan_set(swigCPtr, this, value);
    }

    public boolean getTargetReplan() {
        return RecastJNI.dtCrowdAgent_targetReplan_get(swigCPtr, this);
    }

    public void setTargetReplanTime(float value) {
        RecastJNI.dtCrowdAgent_targetReplanTime_set(swigCPtr, this, value);
    }

    public float getTargetReplanTime() {
        return RecastJNI.dtCrowdAgent_targetReplanTime_get(swigCPtr, this);
    }

    public dtCrowdAgent() {
        this(RecastJNI.new_dtCrowdAgent(), true);
    }
} public class dtCrowdAgentAnimation {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtCrowdAgentAnimation(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtCrowdAgentAnimation obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtCrowdAgentAnimation(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setActive(boolean value) {
    RecastJNI.dtCrowdAgentAnimation_active_set(swigCPtr, this, value);
  }

  public boolean getActive() {
    return RecastJNI.dtCrowdAgentAnimation_active_get(swigCPtr, this);
  }

  public void setInitPos(SWIGTYPE_p_float value) {
    RecastJNI.dtCrowdAgentAnimation_initPos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getInitPos() {
    long cPtr = RecastJNI.dtCrowdAgentAnimation_initPos_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setStartPos(SWIGTYPE_p_float value) {
    RecastJNI.dtCrowdAgentAnimation_startPos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getStartPos() {
    long cPtr = RecastJNI.dtCrowdAgentAnimation_startPos_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setEndPos(SWIGTYPE_p_float value) {
    RecastJNI.dtCrowdAgentAnimation_endPos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getEndPos() {
    long cPtr = RecastJNI.dtCrowdAgentAnimation_endPos_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setPolyRef(long value) {
    RecastJNI.dtCrowdAgentAnimation_polyRef_set(swigCPtr, this, value);
  }

  public long getPolyRef() {
    return RecastJNI.dtCrowdAgentAnimation_polyRef_get(swigCPtr, this);
  }

  public void setT(float value) {
    RecastJNI.dtCrowdAgentAnimation_t_set(swigCPtr, this, value);
  }

  public float getT() {
    return RecastJNI.dtCrowdAgentAnimation_t_get(swigCPtr, this);
  }

  public void setTmax(float value) {
    RecastJNI.dtCrowdAgentAnimation_tmax_set(swigCPtr, this, value);
  }

  public float getTmax() {
    return RecastJNI.dtCrowdAgentAnimation_tmax_get(swigCPtr, this);
  }

  public dtCrowdAgentAnimation() {
    this(RecastJNI.new_dtCrowdAgentAnimation(), true);
  }

} public class dtCrowdAgentDebugInfo {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtCrowdAgentDebugInfo(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtCrowdAgentDebugInfo obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtCrowdAgentDebugInfo(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setIdx(int value) {
    RecastJNI.dtCrowdAgentDebugInfo_idx_set(swigCPtr, this, value);
  }

  public int getIdx() {
    return RecastJNI.dtCrowdAgentDebugInfo_idx_get(swigCPtr, this);
  }

  public void setOptStart(SWIGTYPE_p_float value) {
    RecastJNI.dtCrowdAgentDebugInfo_optStart_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getOptStart() {
    long cPtr = RecastJNI.dtCrowdAgentDebugInfo_optStart_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setOptEnd(SWIGTYPE_p_float value) {
    RecastJNI.dtCrowdAgentDebugInfo_optEnd_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getOptEnd() {
    long cPtr = RecastJNI.dtCrowdAgentDebugInfo_optEnd_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setVod(dtObstacleAvoidanceDebugData value) {
    RecastJNI.dtCrowdAgentDebugInfo_vod_set(swigCPtr, this, dtObstacleAvoidanceDebugData.getCPtr(value), value);
  }

  public dtObstacleAvoidanceDebugData getVod() {
    long cPtr = RecastJNI.dtCrowdAgentDebugInfo_vod_get(swigCPtr, this);
    return (cPtr == 0) ? null : new dtObstacleAvoidanceDebugData(cPtr, false);
  }

  public dtCrowdAgentDebugInfo() {
    this(RecastJNI.new_dtCrowdAgentDebugInfo(), true);
  }

} public class dtCrowdAgentParams {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtCrowdAgentParams(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtCrowdAgentParams obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtCrowdAgentParams(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setRadius(float value) {
    RecastJNI.dtCrowdAgentParams_radius_set(swigCPtr, this, value);
  }

  public float getRadius() {
    return RecastJNI.dtCrowdAgentParams_radius_get(swigCPtr, this);
  }

  public void setHeight(float value) {
    RecastJNI.dtCrowdAgentParams_height_set(swigCPtr, this, value);
  }

  public float getHeight() {
    return RecastJNI.dtCrowdAgentParams_height_get(swigCPtr, this);
  }

  public void setMaxAcceleration(float value) {
    RecastJNI.dtCrowdAgentParams_maxAcceleration_set(swigCPtr, this, value);
  }

  public float getMaxAcceleration() {
    return RecastJNI.dtCrowdAgentParams_maxAcceleration_get(swigCPtr, this);
  }

  public void setMaxSpeed(float value) {
    RecastJNI.dtCrowdAgentParams_maxSpeed_set(swigCPtr, this, value);
  }

  public float getMaxSpeed() {
    return RecastJNI.dtCrowdAgentParams_maxSpeed_get(swigCPtr, this);
  }

  public void setCollisionQueryRange(float value) {
    RecastJNI.dtCrowdAgentParams_collisionQueryRange_set(swigCPtr, this, value);
  }

  public float getCollisionQueryRange() {
    return RecastJNI.dtCrowdAgentParams_collisionQueryRange_get(swigCPtr, this);
  }

  public void setPathOptimizationRange(float value) {
    RecastJNI.dtCrowdAgentParams_pathOptimizationRange_set(swigCPtr, this, value);
  }

  public float getPathOptimizationRange() {
    return RecastJNI.dtCrowdAgentParams_pathOptimizationRange_get(swigCPtr, this);
  }

  public void setSeparationWeight(float value) {
    RecastJNI.dtCrowdAgentParams_separationWeight_set(swigCPtr, this, value);
  }

  public float getSeparationWeight() {
    return RecastJNI.dtCrowdAgentParams_separationWeight_get(swigCPtr, this);
  }

  public void setUpdateFlags(short value) {
    RecastJNI.dtCrowdAgentParams_updateFlags_set(swigCPtr, this, value);
  }

  public short getUpdateFlags() {
    return RecastJNI.dtCrowdAgentParams_updateFlags_get(swigCPtr, this);
  }

  public void setObstacleAvoidanceType(short value) {
    RecastJNI.dtCrowdAgentParams_obstacleAvoidanceType_set(swigCPtr, this, value);
  }

  public short getObstacleAvoidanceType() {
    return RecastJNI.dtCrowdAgentParams_obstacleAvoidanceType_get(swigCPtr, this);
  }

  public void setQueryFilterType(short value) {
    RecastJNI.dtCrowdAgentParams_queryFilterType_set(swigCPtr, this, value);
  }

  public short getQueryFilterType() {
    return RecastJNI.dtCrowdAgentParams_queryFilterType_get(swigCPtr, this);
  }

  public void setUserData(SWIGTYPE_p_void value) {
    RecastJNI.dtCrowdAgentParams_userData_set(swigCPtr, this, SWIGTYPE_p_void.getCPtr(value));
  }

  public SWIGTYPE_p_void getUserData() {
    long cPtr = RecastJNI.dtCrowdAgentParams_userData_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_void(cPtr, false);
  }

  public dtCrowdAgentParams() {
    this(RecastJNI.new_dtCrowdAgentParams(), true);
  }

} public class dtCrowdNeighbour {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtCrowdNeighbour(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtCrowdNeighbour obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtCrowdNeighbour(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setIdx(int value) {
    RecastJNI.dtCrowdNeighbour_idx_set(swigCPtr, this, value);
  }

  public int getIdx() {
    return RecastJNI.dtCrowdNeighbour_idx_get(swigCPtr, this);
  }

  public void setDist(float value) {
    RecastJNI.dtCrowdNeighbour_dist_set(swigCPtr, this, value);
  }

  public float getDist() {
    return RecastJNI.dtCrowdNeighbour_dist_get(swigCPtr, this);
  }

  public dtCrowdNeighbour() {
    this(RecastJNI.new_dtCrowdNeighbour(), true);
  }

} public class dtLocalBoundary {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtLocalBoundary(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtLocalBoundary obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtLocalBoundary(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public dtLocalBoundary() {
    this(RecastJNI.new_dtLocalBoundary(), true);
  }

  public void reset() {
    RecastJNI.dtLocalBoundary_reset(swigCPtr, this);
  }

  public void update(long ref, SWIGTYPE_p_float pos, float collisionQueryRange, NavMeshQuery navquery, QueryFilter filter) {
    RecastJNI.dtLocalBoundary_update(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), collisionQueryRange, NavMeshQuery.getCPtr(navquery), navquery, QueryFilter.getCPtr(filter), filter);
  }

  public boolean isValid(NavMeshQuery navquery, QueryFilter filter) {
    return RecastJNI.dtLocalBoundary_isValid(swigCPtr, this, NavMeshQuery.getCPtr(navquery), navquery, QueryFilter.getCPtr(filter), filter);
  }

  public SWIGTYPE_p_float getCenter() {
    long cPtr = RecastJNI.dtLocalBoundary_getCenter(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public int getSegmentCount() {
    return RecastJNI.dtLocalBoundary_getSegmentCount(swigCPtr, this);
  }

  public SWIGTYPE_p_float getSegment(int i) {
    long cPtr = RecastJNI.dtLocalBoundary_getSegment(swigCPtr, this, i);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

} public class dtObstacleAvoidanceDebugData {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public dtObstacleAvoidanceDebugData() {
        swigCPtr = RecastJNI.dtAllocObstacleAvoidanceDebugData();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }
    
    public dtObstacleAvoidanceDebugData(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(dtObstacleAvoidanceDebugData obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.dtFreeObstacleAvoidanceDebugData(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    

    public boolean init(int maxSamples) {
        return RecastJNI.dtObstacleAvoidanceDebugData_init(swigCPtr, this, maxSamples);
    }

    public void reset() {
        RecastJNI.dtObstacleAvoidanceDebugData_reset(swigCPtr, this);
    }

    public void addSample(SWIGTYPE_p_float vel, float ssize, float pen, float vpen, float vcpen, float spen, float tpen) {
        RecastJNI.dtObstacleAvoidanceDebugData_addSample(swigCPtr, this, SWIGTYPE_p_float.getCPtr(vel), ssize, pen, vpen, vcpen, spen, tpen);
    }

    public void normalizeSamples() {
        RecastJNI.dtObstacleAvoidanceDebugData_normalizeSamples(swigCPtr, this);
    }

    public int getSampleCount() {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSampleCount(swigCPtr, this);
    }

    public SWIGTYPE_p_float getSampleVelocity(int i) {
        long cPtr = RecastJNI.dtObstacleAvoidanceDebugData_getSampleVelocity(swigCPtr, this, i);
        return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
    }

    public float getSampleSize(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSampleSize(swigCPtr, this, i);
    }

    public float getSamplePenalty(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSamplePenalty(swigCPtr, this, i);
    }

    public float getSampleDesiredVelocityPenalty(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSampleDesiredVelocityPenalty(swigCPtr, this, i);
    }

    public float getSampleCurrentVelocityPenalty(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSampleCurrentVelocityPenalty(swigCPtr, this, i);
    }

    public float getSamplePreferredSidePenalty(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSamplePreferredSidePenalty(swigCPtr, this, i);
    }

    public float getSampleCollisionTimePenalty(int i) {
        return RecastJNI.dtObstacleAvoidanceDebugData_getSampleCollisionTimePenalty(swigCPtr, this, i);
    }
} public class dtObstacleAvoidanceParams {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtObstacleAvoidanceParams(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtObstacleAvoidanceParams obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtObstacleAvoidanceParams(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setVelBias(float value) {
    RecastJNI.dtObstacleAvoidanceParams_velBias_set(swigCPtr, this, value);
  }

  public float getVelBias() {
    return RecastJNI.dtObstacleAvoidanceParams_velBias_get(swigCPtr, this);
  }

  public void setWeightDesVel(float value) {
    RecastJNI.dtObstacleAvoidanceParams_weightDesVel_set(swigCPtr, this, value);
  }

  public float getWeightDesVel() {
    return RecastJNI.dtObstacleAvoidanceParams_weightDesVel_get(swigCPtr, this);
  }

  public void setWeightCurVel(float value) {
    RecastJNI.dtObstacleAvoidanceParams_weightCurVel_set(swigCPtr, this, value);
  }

  public float getWeightCurVel() {
    return RecastJNI.dtObstacleAvoidanceParams_weightCurVel_get(swigCPtr, this);
  }

  public void setWeightSide(float value) {
    RecastJNI.dtObstacleAvoidanceParams_weightSide_set(swigCPtr, this, value);
  }

  public float getWeightSide() {
    return RecastJNI.dtObstacleAvoidanceParams_weightSide_get(swigCPtr, this);
  }

  public void setWeightToi(float value) {
    RecastJNI.dtObstacleAvoidanceParams_weightToi_set(swigCPtr, this, value);
  }

  public float getWeightToi() {
    return RecastJNI.dtObstacleAvoidanceParams_weightToi_get(swigCPtr, this);
  }

  public void setHorizTime(float value) {
    RecastJNI.dtObstacleAvoidanceParams_horizTime_set(swigCPtr, this, value);
  }

  public float getHorizTime() {
    return RecastJNI.dtObstacleAvoidanceParams_horizTime_get(swigCPtr, this);
  }

  public void setGridSize(short value) {
    RecastJNI.dtObstacleAvoidanceParams_gridSize_set(swigCPtr, this, value);
  }

  public short getGridSize() {
    return RecastJNI.dtObstacleAvoidanceParams_gridSize_get(swigCPtr, this);
  }

  public void setAdaptiveDivs(short value) {
    RecastJNI.dtObstacleAvoidanceParams_adaptiveDivs_set(swigCPtr, this, value);
  }

  public short getAdaptiveDivs() {
    return RecastJNI.dtObstacleAvoidanceParams_adaptiveDivs_get(swigCPtr, this);
  }

  public void setAdaptiveRings(short value) {
    RecastJNI.dtObstacleAvoidanceParams_adaptiveRings_set(swigCPtr, this, value);
  }

  public short getAdaptiveRings() {
    return RecastJNI.dtObstacleAvoidanceParams_adaptiveRings_get(swigCPtr, this);
  }

  public void setAdaptiveDepth(short value) {
    RecastJNI.dtObstacleAvoidanceParams_adaptiveDepth_set(swigCPtr, this, value);
  }

  public short getAdaptiveDepth() {
    return RecastJNI.dtObstacleAvoidanceParams_adaptiveDepth_get(swigCPtr, this);
  }

  public dtObstacleAvoidanceParams() {
    this(RecastJNI.new_dtObstacleAvoidanceParams(), true);
  }

} public class dtObstacleAvoidanceQuery {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public dtObstacleAvoidanceQuery() {
        swigCPtr = RecastJNI.dtAllocObstacleAvoidanceQuery();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    public dtObstacleAvoidanceQuery(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(dtObstacleAvoidanceQuery obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.dtFreeObstacleAvoidanceQuery(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    public boolean init(int maxCircles, int maxSegments) {
        return RecastJNI.dtObstacleAvoidanceQuery_init(swigCPtr, this, maxCircles, maxSegments);
    }

    public void reset() {
        RecastJNI.dtObstacleAvoidanceQuery_reset(swigCPtr, this);
    }

    public void addCircle(SWIGTYPE_p_float pos, float rad, SWIGTYPE_p_float vel, SWIGTYPE_p_float dvel) {
        RecastJNI.dtObstacleAvoidanceQuery_addCircle(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), rad, SWIGTYPE_p_float.getCPtr(vel), SWIGTYPE_p_float.getCPtr(dvel));
    }

    public void addSegment(SWIGTYPE_p_float p, SWIGTYPE_p_float q) {
        RecastJNI.dtObstacleAvoidanceQuery_addSegment(swigCPtr, this, SWIGTYPE_p_float.getCPtr(p), SWIGTYPE_p_float.getCPtr(q));
    }

    public int sampleVelocityGrid(SWIGTYPE_p_float pos, float rad, float vmax, SWIGTYPE_p_float vel, SWIGTYPE_p_float dvel, SWIGTYPE_p_float nvel, dtObstacleAvoidanceParams params, dtObstacleAvoidanceDebugData debug) {
        return RecastJNI.dtObstacleAvoidanceQuery_sampleVelocityGrid__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), rad, vmax, SWIGTYPE_p_float.getCPtr(vel), SWIGTYPE_p_float.getCPtr(dvel), SWIGTYPE_p_float.getCPtr(nvel), dtObstacleAvoidanceParams.getCPtr(params), params, dtObstacleAvoidanceDebugData.getCPtr(debug), debug);
    }

    public int sampleVelocityGrid(SWIGTYPE_p_float pos, float rad, float vmax, SWIGTYPE_p_float vel, SWIGTYPE_p_float dvel, SWIGTYPE_p_float nvel, dtObstacleAvoidanceParams params) {
        return RecastJNI.dtObstacleAvoidanceQuery_sampleVelocityGrid__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), rad, vmax, SWIGTYPE_p_float.getCPtr(vel), SWIGTYPE_p_float.getCPtr(dvel), SWIGTYPE_p_float.getCPtr(nvel), dtObstacleAvoidanceParams.getCPtr(params), params);
    }

    public int sampleVelocityAdaptive(SWIGTYPE_p_float pos, float rad, float vmax, SWIGTYPE_p_float vel, SWIGTYPE_p_float dvel, SWIGTYPE_p_float nvel, dtObstacleAvoidanceParams params, dtObstacleAvoidanceDebugData debug) {
        return RecastJNI.dtObstacleAvoidanceQuery_sampleVelocityAdaptive__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), rad, vmax, SWIGTYPE_p_float.getCPtr(vel), SWIGTYPE_p_float.getCPtr(dvel), SWIGTYPE_p_float.getCPtr(nvel), dtObstacleAvoidanceParams.getCPtr(params), params, dtObstacleAvoidanceDebugData.getCPtr(debug), debug);
    }

    public int sampleVelocityAdaptive(SWIGTYPE_p_float pos, float rad, float vmax, SWIGTYPE_p_float vel, SWIGTYPE_p_float dvel, SWIGTYPE_p_float nvel, dtObstacleAvoidanceParams params) {
        return RecastJNI.dtObstacleAvoidanceQuery_sampleVelocityAdaptive__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), rad, vmax, SWIGTYPE_p_float.getCPtr(vel), SWIGTYPE_p_float.getCPtr(dvel), SWIGTYPE_p_float.getCPtr(nvel), dtObstacleAvoidanceParams.getCPtr(params), params);
    }

    public int getObstacleCircleCount() {
        return RecastJNI.dtObstacleAvoidanceQuery_getObstacleCircleCount(swigCPtr, this);
    }

    public dtObstacleCircle getObstacleCircle(int i) {
        long cPtr = RecastJNI.dtObstacleAvoidanceQuery_getObstacleCircle(swigCPtr, this, i);
        return (cPtr == 0) ? null : new dtObstacleCircle(cPtr, false);
    }

    public int getObstacleSegmentCount() {
        return RecastJNI.dtObstacleAvoidanceQuery_getObstacleSegmentCount(swigCPtr, this);
    }

    public dtObstacleSegment getObstacleSegment(int i) {
        long cPtr = RecastJNI.dtObstacleAvoidanceQuery_getObstacleSegment(swigCPtr, this, i);
        return (cPtr == 0) ? null : new dtObstacleSegment(cPtr, false);
    }
} public class dtObstacleCircle {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtObstacleCircle(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtObstacleCircle obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtObstacleCircle(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setP(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleCircle_p_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getP() {
    long cPtr = RecastJNI.dtObstacleCircle_p_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setVel(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleCircle_vel_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getVel() {
    long cPtr = RecastJNI.dtObstacleCircle_vel_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setDvel(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleCircle_dvel_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getDvel() {
    long cPtr = RecastJNI.dtObstacleCircle_dvel_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setRad(float value) {
    RecastJNI.dtObstacleCircle_rad_set(swigCPtr, this, value);
  }

  public float getRad() {
    return RecastJNI.dtObstacleCircle_rad_get(swigCPtr, this);
  }

  public void setDp(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleCircle_dp_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getDp() {
    long cPtr = RecastJNI.dtObstacleCircle_dp_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setNp(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleCircle_np_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getNp() {
    long cPtr = RecastJNI.dtObstacleCircle_np_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public dtObstacleCircle() {
    this(RecastJNI.new_dtObstacleCircle(), true);
  }

} public class dtObstacleSegment {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtObstacleSegment(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtObstacleSegment obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtObstacleSegment(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setP(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleSegment_p_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getP() {
    long cPtr = RecastJNI.dtObstacleSegment_p_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setQ(SWIGTYPE_p_float value) {
    RecastJNI.dtObstacleSegment_q_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
  }

  public SWIGTYPE_p_float getQ() {
    long cPtr = RecastJNI.dtObstacleSegment_q_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_float(cPtr, false);
  }

  public void setTouch(boolean value) {
    RecastJNI.dtObstacleSegment_touch_set(swigCPtr, this, value);
  }

  public boolean getTouch() {
    return RecastJNI.dtObstacleSegment_touch_get(swigCPtr, this);
  }

  public dtObstacleSegment() {
    this(RecastJNI.new_dtObstacleSegment(), true);
  }

} public class dtPathQueue {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtPathQueue(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtPathQueue obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtPathQueue(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public dtPathQueue() {
    this(RecastJNI.new_dtPathQueue(), true);
  }

  public boolean init(int maxPathSize, int maxSearchNodeCount, NavMesh nav) {
    return RecastJNI.dtPathQueue_init(swigCPtr, this, maxPathSize, maxSearchNodeCount, NavMesh.getCPtr(nav), nav);
  }

  public void update(int maxIters) {
    RecastJNI.dtPathQueue_update(swigCPtr, this, maxIters);
  }

  public long request(long startRef, long endRef, SWIGTYPE_p_float startPos, SWIGTYPE_p_float endPos, QueryFilter filter) {
    return RecastJNI.dtPathQueue_request(swigCPtr, this, startRef, endRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter);
  }

  public long getRequestStatus(long ref) {
    return RecastJNI.dtPathQueue_getRequestStatus(swigCPtr, this, ref);
  }

  public long getPathResult(long ref, SWIGTYPE_p_unsigned_int path, SWIGTYPE_p_int pathSize, int maxPath) {
    return RecastJNI.dtPathQueue_getPathResult(swigCPtr, this, ref, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathSize), maxPath);
  }

  public NavMeshQuery getNavQuery() {
    long cPtr = RecastJNI.dtPathQueue_getNavQuery(swigCPtr, this);
    return (cPtr == 0) ? null : new NavMeshQuery(cPtr, false);
  }

} public class dtProximityGrid {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public dtProximityGrid(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(dtProximityGrid obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        RecastJNI.delete_dtProximityGrid(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public dtProximityGrid() {
    this(RecastJNI.new_dtProximityGrid(), true);
  }

  public boolean init(int maxItems, float cellSize) {
    return RecastJNI.dtProximityGrid_init(swigCPtr, this, maxItems, cellSize);
  }

  public void clear() {
    RecastJNI.dtProximityGrid_clear(swigCPtr, this);
  }

  public void addItem(int id, float minx, float miny, float maxx, float maxy) {
    RecastJNI.dtProximityGrid_addItem(swigCPtr, this, id, minx, miny, maxx, maxy);
  }

  public int queryItems(float minx, float miny, float maxx, float maxy, SWIGTYPE_p_unsigned_short ids, int maxIds) {
    return RecastJNI.dtProximityGrid_queryItems(swigCPtr, this, minx, miny, maxx, maxy, SWIGTYPE_p_unsigned_short.getCPtr(ids), maxIds);
  }

  public int getItemCountAt(int x, int y) {
    return RecastJNI.dtProximityGrid_getItemCountAt(swigCPtr, this, x, y);
  }

  public SWIGTYPE_p_int getBounds() {
    long cPtr = RecastJNI.dtProximityGrid_getBounds(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_int(cPtr, false);
  }

  public float getCellSize() {
    return RecastJNI.dtProximityGrid_getCellSize(swigCPtr, this);
  }

} public class BVNode {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public BVNode() {
        this(RecastJNI.new_dtBVNode(), true);
    }

    public BVNode(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(BVNode obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtBVNode(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param minBounds Minimum bounds of the node's AABB.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(minBounds);
        RecastJNI.dtBVNode_bmin_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Minimum bounds of the node's AABB.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.dtBVNode_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds Maximum bounds of the node's AABB.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(maxBounds);
        RecastJNI.dtBVNode_bmax_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Maximum bounds of the node's AABB.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.dtBVNode_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param index The node's index. (Negative for escape sequence.)
     */
    public void setNodeIndex(int index) {
        RecastJNI.dtBVNode_i_set(swigCPtr, this, index);
    }

    /**
     *
     * @return The node's index. (Negative for escape sequence.)
     */
    public int getNodeIndex() {
        return RecastJNI.dtBVNode_i_get(swigCPtr, this);
    }
} public class Link {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public Link() {
        this(RecastJNI.new_dtLink(), true);
    }

    public Link(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Link obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtLink(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value Neighbour reference. (The neighbor that is linked to.)
     */
    public void setReference(long value) {
        RecastJNI.dtLink_ref_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Neighbour reference. (The neighbor that is linked to.)
     */
    public long getReference() {
        return RecastJNI.dtLink_ref_get(swigCPtr, this);
    }

    /**
     *
     * @param value Index of the next link.
     */
    public void setNext(long value) {
        RecastJNI.dtLink_next_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Index of the next link.
     */
    public long getNext() {
        return RecastJNI.dtLink_next_get(swigCPtr, this);
    }

    /**
     *
     * @param value Index of the polygon edge that owns this link.
     */
    public void setEdge(short value) {
        RecastJNI.dtLink_edge_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Index of the polygon edge that owns this link.
     */
    public short getEdge() {
        return RecastJNI.dtLink_edge_get(swigCPtr, this);
    }

    /**
     *
     * @param value If a boundary link, defines on which side the link is.
     */
    public void setSide(short value) {
        RecastJNI.dtLink_side_set(swigCPtr, this, value);
    }

    /**
     *
     * @return If a boundary link, defines on which side the link is.
     */
    public short getSide() {
        return RecastJNI.dtLink_side_get(swigCPtr, this);
    }

    /**
     *
     * @param value If a boundary link, defines the minimum sub-edge area.
     */
    public void setMinBoundary(short value) {
        RecastJNI.dtLink_bmin_set(swigCPtr, this, value);
    }

    /**
     *
     * @return If a boundary link, defines the minimum sub-edge area.
     */
    public short getMinBoundary() {
        return RecastJNI.dtLink_bmin_get(swigCPtr, this);
    }

    /**
     *
     * @param value If a boundary link, defines the maximum sub-edge area.
     */
    public void setMaxBoundary(short value) {
        RecastJNI.dtLink_bmax_set(swigCPtr, this, value);
    }

    /**
     *
     * @return If a boundary link, defines the maximum sub-edge area.
     */
    public short getMaxBoundary() {
        return RecastJNI.dtLink_bmax_get(swigCPtr, this);
    }
} public class MeshHeader {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public MeshHeader() {
        this(RecastJNI.new_dtMeshHeader(), true);
    }

    protected MeshHeader(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(MeshHeader obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtMeshHeader(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value Tile magic number. (Used to identify the data format.)
     */
    public void setMagic(int value) {
        RecastJNI.dtMeshHeader_magic_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Tile magic number. (Used to identify the data format.)
     */
    public int getMagic() {
        return RecastJNI.dtMeshHeader_magic_get(swigCPtr, this);
    }

    /**
     *
     * @param value Tile data format version number.
     */
    public void setVersion(int value) {
        RecastJNI.dtMeshHeader_version_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Tile data format version number.
     */
    public int getVersion() {
        return RecastJNI.dtMeshHeader_version_get(swigCPtr, this);
    }

    /**
     *
     * @param value The x-position of the tile within the NavMesh tile grid. (x,
     * y, layer)
     * @see NavMesh
     */
    public void setX(int value) {
        RecastJNI.dtMeshHeader_x_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The x-position of the tile within the NavMesh tile grid. (x, y,
     * layer)
     * @see NavMesh
     */
    public int getX() {
        return RecastJNI.dtMeshHeader_x_get(swigCPtr, this);
    }

    /**
     *
     * @param value The y-position of the tile within the NavMesh tile grid. (x,
     * y, layer)
     * @see NavMesh
     */
    public void setY(int value) {
        RecastJNI.dtMeshHeader_y_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The y-position of the tile within the NavMesh tile grid. (x, y,
     * layer)
     * @see NavMesh
     */
    public int getY() {
        return RecastJNI.dtMeshHeader_y_get(swigCPtr, this);
    }

    /**
     *
     * @param value The layer of the tile within the NavMesh tile grid. (x, y,
     * layer)
     * @see NavMesh
     */
    public void setLayer(int value) {
        RecastJNI.dtMeshHeader_layer_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The layer of the tile within the NavMesh tile grid. (x, y, layer)
     * @see NavMesh
     */
    public int getLayer() {
        return RecastJNI.dtMeshHeader_layer_get(swigCPtr, this);
    }

    /**
     *
     * @param value The user defined id of the tile.
     */
    public void setUserId(long value) {
        RecastJNI.dtMeshHeader_userId_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The user defined id of the tile.
     */
    public long getUserId() {
        return RecastJNI.dtMeshHeader_userId_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of polygons in the tile.
     */
    public void setPolyCount(int value) {
        RecastJNI.dtMeshHeader_polyCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of polygons in the tile.
     */
    public int getPolyCount() {
        return RecastJNI.dtMeshHeader_polyCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of vertices in the tile.
     */
    public void setVerticesCount(int value) {
        RecastJNI.dtMeshHeader_vertCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices in the tile.
     */
    public int getVerticesCount() {
        return RecastJNI.dtMeshHeader_vertCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of allocated links.
     */
    public void setMaxLinkCount(int value) {
        RecastJNI.dtMeshHeader_maxLinkCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of allocated links.
     */
    public int getMaxLinkCount() {
        return RecastJNI.dtMeshHeader_maxLinkCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of sub-meshes in the detail mesh.
     */
    public void setDetailMeshCount(int value) {
        RecastJNI.dtMeshHeader_detailMeshCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of sub-meshes in the detail mesh.
     */
    public int getDetailMeshCount() {
        return RecastJNI.dtMeshHeader_detailMeshCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of unique vertices in the detail mesh. (In
     * addition to the polygon vertices.)
     */
    public void setDetailVertCount(int value) {
        RecastJNI.dtMeshHeader_detailVertCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of unique vertices in the detail mesh. (In addition to
     * the polygon vertices.)
     */
    public int getDetailVerticesCount() {
        return RecastJNI.dtMeshHeader_detailVertCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of triangles in the detail mesh.
     */
    public void setDetailTrianglesCount(int value) {
        RecastJNI.dtMeshHeader_detailTriCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of triangles in the detail mesh.
     */
    public int getDetailTrianglesCount() {
        return RecastJNI.dtMeshHeader_detailTriCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of bounding volume nodes. (Zero if bounding
     * volumes are disabled.)
     */
    public void setBvNodeCount(int value) {
        RecastJNI.dtMeshHeader_bvNodeCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of bounding volume nodes. (Zero if bounding volumes
     * are disabled.)
     */
    public int getBvNodeCount() {
        return RecastJNI.dtMeshHeader_bvNodeCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of off-mesh connections.
     */
    public void setOffMeshConnectionsCount(int value) {
        RecastJNI.dtMeshHeader_offMeshConCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of off-mesh connections.
     */
    public int getOffMeshConnectionsCount() {
        return RecastJNI.dtMeshHeader_offMeshConCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The index of the first polygon which is an off-mesh
     * connection.
     */
    public void setOffMeshBase(int value) {
        RecastJNI.dtMeshHeader_offMeshBase_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The index of the first polygon which is an off-mesh connection.
     */
    public int getOffMeshBase() {
        return RecastJNI.dtMeshHeader_offMeshBase_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of the agents using the tile.
     */
    public void setWalkableHeight(float value) {
        RecastJNI.dtMeshHeader_walkableHeight_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the agents using the tile.
     */
    public float getWalkableHeight() {
        return RecastJNI.dtMeshHeader_walkableHeight_get(swigCPtr, this);
    }

    /**
     *
     * @param value The radius of the agents using the tile.
     */
    public void setWalkableRadius(float value) {
        RecastJNI.dtMeshHeader_walkableRadius_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The radius of the agents using the tile.
     */
    public float getWalkableRadius() {
        return RecastJNI.dtMeshHeader_walkableRadius_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum climb height of the agents using the tile.
     */
    public void setWalkableClimb(float value) {
        RecastJNI.dtMeshHeader_walkableClimb_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum climb height of the agents using the tile.
     */
    public float getWalkableClimb() {
        return RecastJNI.dtMeshHeader_walkableClimb_get(swigCPtr, this);
    }

    /**
     *
     * @param minBound The minimum bounds of the tile's AABB.
     */
    public void setMinBound(Vector3f minBound) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBound);
        RecastJNI.dtMeshHeader_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds of the tile's AABB.
     */
    public Vector3f getMinBound() {
        long cPtr = RecastJNI.dtMeshHeader_bmin_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBound The maximum bounds of the tile's AABB.
     */
    public void setMaxBound(Vector3f maxBound) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBound);
        RecastJNI.dtMeshHeader_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds of the tile's AABB.
     */
    public Vector3f getMaxBound() {
        long cPtr = RecastJNI.dtMeshHeader_bmax_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The bounding volume quantization factor.
     *
     * This value is used for converting between world and bounding volume
     * coordinates.
     */
    public void setBvQuantFactor(float value) {
        RecastJNI.dtMeshHeader_bvQuantFactor_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The bounding volume quantization factor.
     *
     * This value is used for converting between world and bounding volume
     * coordinates.
     */
    public float getBvQuantFactor() {
        return RecastJNI.dtMeshHeader_bvQuantFactor_get(swigCPtr, this);
    }
} public class MeshTile {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public MeshTile() {
        this(RecastJNI.new_dtMeshTile(), true);
    }

    public MeshTile(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(MeshTile obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtMeshTile(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value Counter describing modifications to the tile.
     */
    public void setSalt(long value) {
        RecastJNI.dtMeshTile_salt_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Counter describing modifications to the tile.
     */
    public long getSalt() {
        return RecastJNI.dtMeshTile_salt_get(swigCPtr, this);
    }

//    /**
//     *
//     * @param value Index to the next free link.
//     */
//    public void setLinksFreeList(long value) {
//        RecastJNI.dtMeshTile_linksFreeList_set(swigCPtr, this, value);
//    }

    /**
     *
     * @return Index to the next free link.
     */
    public long getLinksFreeList() {
        return RecastJNI.dtMeshTile_linksFreeList_get(swigCPtr, this);
    }

    /**
     *
     * @param value The tile header.
     */
    public void setHeader(MeshHeader value) {
        RecastJNI.dtMeshTile_header_set(swigCPtr, this, MeshHeader.getCPtr(value), value);
    }

    /**
     *
     * @return The tile header.
     */
    public MeshHeader getHeader() {
        long cPtr = RecastJNI.dtMeshTile_header_get(swigCPtr, this);
        return (cPtr == 0) ? null : new MeshHeader(cPtr, false);
    }

    /**
     *
     * @param value The tile polygons.
     */
    public void setPolys(Poly value) {
        RecastJNI.dtMeshTile_polys_set(swigCPtr, this, Poly.getCPtr(value), value);
    }

    /**
     *
     * @return The tile polygons.
     */
    public Poly[] getPolys() {
        long cPtr = RecastJNI.dtMeshTile_polys_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToPolys(cPtr, getHeader().getPolyCount());
    }

    /**
     *
     * @param vertices The tile vertices.
     */
    public void setVertices(Vector3f[] vertices) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(vertices);
        RecastJNI.dtMeshTile_verts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The tile vertices.
     */
    public Vector3f[] getVertices() {
        long cPtr = RecastJNI.dtMeshTile_verts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, getHeader().getVerticesCount());
    }

    /**
     *
     * @param value The tile links.
     */
    public void setLinks(Link[] value) {
        RecastJNI.dtMeshTile_links_set(swigCPtr, this, Link.getCPtr(value[0]), value[0]);
    }

    /**
     *
     * @return The tile links.
     */
    public Link[] getLinks() {
        long cPtr = RecastJNI.dtMeshTile_links_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToLinks(cPtr, getHeader().getMaxLinkCount());
    }

    /**
     *
     * @param value The tile's detail sub-meshes.
     */
    public void setDetailMeshes(PolyDetail[] value) {
        RecastJNI.dtMeshTile_detailMeshes_set(swigCPtr, this, PolyDetail.getCPtr(value[0]), value[0]);
    }

    /**
     *
     * @return The tile's detail sub-meshes.
     */
    public PolyDetail[] getDetailMeshes() {
        long cPtr = RecastJNI.dtMeshTile_detailMeshes_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToPolyDetails(cPtr, getHeader().getDetailMeshCount());
    }

    /**
     *
     * @param detailVertices The detail mesh's unique vertices. [(x, y, z) *
     */
    public void setDetailVertices(Vector3f[] detailVertices) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(detailVertices);
        RecastJNI.dtMeshTile_detailVerts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The detail mesh's unique vertices. [(x, y, z) *
     */
    public Vector3f[] getDetailVertices() {
        long cPtr = RecastJNI.dtMeshTile_detailVerts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, getHeader().getDetailVerticesCount());
    }

    /**
     *
     * @param detailTriangles The detail mesh's triangles. [(vertA, vertB,
     * vertC)]
     */
    public void setDetailTriangles(char[] detailTriangles) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(detailTriangles);
        RecastJNI.dtMeshTile_detailTris_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return The detail mesh's triangles. [(vertA, vertB, vertC)]
     */
    public char[] getDetailTriangles() {
        long cPtr = RecastJNI.dtMeshTile_detailTris_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getHeader().getDetailTrianglesCount() * 3);
    }

    /**
     * -not tested yet
     *
     * @param value The tile bounding volume nodes.
     */
    public void setBvTree(BVNode value) {
        RecastJNI.dtMeshTile_bvTree_set(swigCPtr, this, BVNode.getCPtr(value), value);
    }

    /**
     * -not tested yet
     *
     * @return The tile bounding volume nodes.
     */
    public BVNode getBvTree() {
        long cPtr = RecastJNI.dtMeshTile_bvTree_get(swigCPtr, this);
        return (cPtr == 0) ? null : new BVNode(cPtr, false);
    }

    /**
     *
     * @param value The tile off-mesh connections.
     */
    public void setOffMeshConnections(OffMeshConnection value) {
        RecastJNI.dtMeshTile_offMeshCons_set(swigCPtr, this, OffMeshConnection.getCPtr(value), value);
    }

    /**
     *
     * @return The tile off-mesh connections.
     */
    public OffMeshConnection[] getOffMeshConnections() {
        long cPtr = RecastJNI.dtMeshTile_offMeshCons_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToOffMeshConnections(cPtr, getHeader().getOffMeshConnectionsCount());
    }

    /**
     *
     * @param data The tile data. (Not directly accessed under normal
     * situations.)
     */
    public void setData(char[] data) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        RecastJNI.dtMeshTile_data_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return The tile data. (Not directly accessed under normal situations.)
     */
    public char[] getData() {
        long cPtr = RecastJNI.dtMeshTile_data_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getDataSize());
    }

    /**
     *
     * @param value Size of the tile data.
     */
    public void setDataSize(int value) {
        RecastJNI.dtMeshTile_dataSize_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Size of the tile data.
     */
    public int getDataSize() {
        return RecastJNI.dtMeshTile_dataSize_get(swigCPtr, this);
    }

    /**
     *
     * @param value Tile flags.
     */
    public void setFlags(int value) {
        RecastJNI.dtMeshTile_flags_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Tile flags.
     */
    public int getFlags() {
        return RecastJNI.dtMeshTile_flags_get(swigCPtr, this);
    }

    /**
     *
     * @param value The next free tile, or the next tile in the spatial grid.
     */
    public void setNext(MeshTile value) {
        RecastJNI.dtMeshTile_next_set(swigCPtr, this, MeshTile.getCPtr(value), value);
    }

    /**
     *
     * @return The next free tile, or the next tile in the spatial grid.
     */
    public MeshTile getNext() {
        long cPtr = RecastJNI.dtMeshTile_next_get(swigCPtr, this);
        return (cPtr == 0) ? null : new MeshTile(cPtr, false);
    }

    protected void setSwigCPtr(long swigCPtr) {
        if (this.swigCPtr==swigCPtr) {
            return;
        }
        delete();
        this.swigCPtr = swigCPtr;
    }
} public class NavMesh {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NavMesh() {
        swigCPtr = RecastJNI.dtAllocNavMesh();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected NavMesh(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NavMesh obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.dtFreeNavMesh(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     * Initializes the navigation mesh for tiled use.
     *
     * @param params Initialization parameters.
     * @return The status flags for the operation.
     */
    public Status init(NavMeshParams params) {
        return new Status(RecastJNI.dtNavMesh_init__SWIG_0(swigCPtr, this, NavMeshParams.getCPtr(params), params));
    }

    /**
     * Initializes the navigation mesh for single tile use.
     *
     * @see
     * DetourBuilder#createNavMeshData(com.jme3.ai.navigation.detour.NavMeshCreateParams)
     * @see TileFlags
     *
     * @param data Data of the new tile.
     * @param flags The tile flags.
     * @return
     */
    public Status init(char[] data, int flags) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        int dataSize = data.length;
        return new Status(RecastJNI.dtNavMesh_init__SWIG_1(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value), dataSize, flags));
    }

    /**
     * The navigation mesh initialization params.
     *
     * Note: The parameters are created automatically when the single tile
     * initialization is performed.
     *
     * @return
     */
    public NavMeshParams getParams() {
        long cPtr = RecastJNI.dtNavMesh_getParams(swigCPtr, this);
        return (cPtr == 0) ? null : new NavMeshParams(cPtr, false);
    }

    /**
     * Adds a tile to the navigation mesh. The add operation will fail if the
     * data is in the wrong format, the allocated tile space is full, or there
     * is a tile already at the specified reference.
     *
     * The lastRef parameter is used to restore a tile with the same tile
     * reference it had previously used. In this case the PolyRef's for the tile
     * will be restored to the same values they were before the tile was
     * removed.
     *
     * @param data Data for the new tile mesh.
     * @param flags Tile flags
     * @see TileFlags
     * @param lastRef The desired reference for the tile. (When reloading a
     * tile.) [opt] [Default: 0]
     * @param result The tile reference. (If the tile was succesfully added.)
     * [opt]
     * @return The status flags for the operation.
     */
    public Status addTile(char[] data, int flags, long lastRef, int[] result) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        int dataSize = data.length;
        SWIGTYPE_p_unsigned_int value1 = Converter.convertToSWIGTYPE_p_unsigned_int(result);
        return new Status(RecastJNI.dtNavMesh_addTile(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value), dataSize, flags, lastRef, SWIGTYPE_p_unsigned_int.getCPtr(value1)));
    }

    //data is output too
    public Status removeTile(long ref, SWIGTYPE_p_p_unsigned_char data, SWIGTYPE_p_int dataSize) {
        return new Status(RecastJNI.dtNavMesh_removeTile(swigCPtr, this, ref, SWIGTYPE_p_p_unsigned_char.getCPtr(data), SWIGTYPE_p_int.getCPtr(dataSize)));
    }

    /**
     * Calculates the tile grid location X for the specified world position.
     *
     * @param position The world position for the query.
     * @return The tile's x-location.
     */
    public int calculateTileLocationX(Vector3f position) {
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_int tx = new IntArray(1).cast();
        SWIGTYPE_p_int ty = new IntArray(1).cast();
        RecastJNI.dtNavMesh_calcTileLoc(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_int.getCPtr(tx), SWIGTYPE_p_int.getCPtr(ty));
        IntArray a = new IntArray(SWIGTYPE_p_int.getCPtr(tx), false);
        return a.getItem(0);
    }

    /**
     * Calculates the tile grid location Y for the specified world position.
     *
     * @param position The world position for the query.
     * @return The tile's y-location.
     */
    public int calculateTileLocationY(Vector3f position) {
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_int tx = new IntArray(1).cast();
        SWIGTYPE_p_int ty = new IntArray(1).cast();
        RecastJNI.dtNavMesh_calcTileLoc(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_int.getCPtr(tx), SWIGTYPE_p_int.getCPtr(ty));
        IntArray a = new IntArray(SWIGTYPE_p_int.getCPtr(ty), false);
        return a.getItem(0);
    }

    /**
     * Gets the tile at the specified grid location.
     *
     * @param x The tile's x-location. (x, y, layer)
     * @param y The tile's y-location. (x, y, layer)
     * @param layer The tile's layer. (x, y, layer)
     * @return The tile, or null if the tile does not exist.
     */
    public MeshTile getTileAt(int x, int y, int layer) {
        long cPtr = RecastJNI.dtNavMesh_getTileAt(swigCPtr, this, x, y, layer);
        return (cPtr == 0) ? null : new MeshTile(cPtr, false);
    }
//  - not operational
//    public MeshTile[] getTilesAt(int x, int y, int maxTiles) {
//        SWIGTYPE_p_p_dtMeshTile tiles = 
//        return RecastJNI.dtNavMesh_getTilesAt(swigCPtr, this, x, y, SWIGTYPE_p_p_dtMeshTile.getCPtr(tiles), maxTiles);
//    }

    /**
     * Gets the tile reference for the tile at specified grid location.
     *
     * @param x The tile's x-location. (x, y, layer)
     * @param y The tile's y-location. (x, y, layer)
     * @param layer The tile's layer. (x, y, layer)
     * @return The tile reference of the tile, or 0 if there is none.
     */
    public long getTileRefAt(int x, int y, int layer) {
        return RecastJNI.dtNavMesh_getTileRefAt(swigCPtr, this, x, y, layer);
    }

    /**
     * Gets the tile reference for the specified tile.
     *
     * @param tile The tile.
     * @return The tile reference of the tile.
     */
    public long getTileRef(MeshTile tile) {
        return RecastJNI.dtNavMesh_getTileRef(swigCPtr, this, MeshTile.getCPtr(tile), tile);
    }

    /**
     * Gets the tile for the specified tile reference.
     *
     * @param ref The tile reference of the tile to retrieve.
     * @return The tile for the specified reference, or null if the reference is
     * invalid.
     */
    public MeshTile getTileByRef(long ref) {
        long cPtr = RecastJNI.dtNavMesh_getTileByRef(swigCPtr, this, ref);
        return (cPtr == 0) ? null : new MeshTile(cPtr, false);
    }

    /**
     *
     * @return The maximum number of tiles supported by the navigation mesh.
     */
    public int getMaxTiles() {
        return RecastJNI.dtNavMesh_getMaxTiles(swigCPtr, this);
    }

    /**
     * Gets the tile at the specified index.
     *
     * @param i The tile index. [Limit: 0 >= index less than getMaxTiles()]
     *
     * @return The tile at the specified index.
     */
    public MeshTile getTile(int i) {
        long cPtr = RecastJNI.dtNavMesh_getTile(swigCPtr, this, i);
        return (cPtr == 0) ? null : new MeshTile(cPtr, false);
    }

    /**
     * Gets the tile and polygon for the specified polygon reference.
     *
     * @param ref The reference for the a polygon.
     * @param meshTile The tile containing the polygon. [out]
     * @param poly The polygon. [out]
     * @return The status flags for the operation.
     */
    public Status getTileAndPolyByRef(long ref, MeshTile meshTile, Poly poly) {
        SWIGTYPE_p_p_dtMeshTile tile = new SWIGTYPE_p_p_dtMeshTile(MeshTile.getCPtr(meshTile), false);
        SWIGTYPE_p_p_dtPoly poly1 = new SWIGTYPE_p_p_dtPoly(Poly.getCPtr(poly), false);
        long ptr = RecastJNI.dtNavMesh_getTileAndPolyByRef(swigCPtr, this, ref, SWIGTYPE_p_p_dtMeshTile.getCPtr(tile), SWIGTYPE_p_p_dtPoly.getCPtr(poly1));
        meshTile.setSwigCPtr(SWIGTYPE_p_p_dtMeshTile.getCPtr(tile));
        poly.setSwigCPtr(SWIGTYPE_p_p_dtPoly.getCPtr(poly1));
        return (ptr == 0) ? null : new Status(ptr);
    }

    /**
     * Returns the tile and polygon for the specified polygon reference.
     *
     * WARNING: Only use this function if it is known that the provided polygon
     * reference is valid. This function is faster than getTileAndPolyByRef, but
     * it does not validate the reference.
     *
     * @see NavMesh#getTileAndPolyByRef(long,
     * com.jme3.ai.navigation.detour.MeshTile,
     * com.jme3.ai.navigation.detour.Poly)
     *
     * @param ref A known valid reference for a polygon.
     * @param meshTile The tile containing the polygon. [out]
     * @param poly The polygon. [out]
     */
    public void getTileAndPolyByRefUnsafe(long ref, MeshTile meshTile, Poly poly) {
        SWIGTYPE_p_p_dtMeshTile tile = new SWIGTYPE_p_p_dtMeshTile(MeshTile.getCPtr(meshTile), false);
        SWIGTYPE_p_p_dtPoly poly1 = new SWIGTYPE_p_p_dtPoly(Poly.getCPtr(poly), false);
        RecastJNI.dtNavMesh_getTileAndPolyByRefUnsafe(swigCPtr, this, ref, SWIGTYPE_p_p_dtMeshTile.getCPtr(tile), SWIGTYPE_p_p_dtPoly.getCPtr(poly1));
        meshTile.setSwigCPtr(SWIGTYPE_p_p_dtMeshTile.getCPtr(tile));
        poly.setSwigCPtr(SWIGTYPE_p_p_dtPoly.getCPtr(poly1));
    }

    /**
     * Checks the validity of a polygon reference.
     *
     * @param ref The polygon reference to check.
     * @return True if polygon reference is valid for the navigation mesh.
     */
    public boolean isValidPolyRef(long ref) {
        return RecastJNI.dtNavMesh_isValidPolyRef(swigCPtr, this, ref);
    }

    /**
     * Gets the polygon reference for the tile's base polygon.
     *
     * @param tile The tile.
     * @return The polygon reference for the base polygon in the specified tile.
     */
    public Poly getPolyRefBase(MeshTile tile) {
        long ref = RecastJNI.dtNavMesh_getPolyRefBase(swigCPtr, this, MeshTile.getCPtr(tile), tile);
        return (ref == 0) ? null : new Poly(ref, false);
    }

    /**
     * Gets the endpoints for an off-mesh connection, ordered by "direction of
     * travel".
     *
     * Off-mesh connections are stored in the navigation mesh as special
     * 2-vertex polygons with a single edge. At least one of the vertices is
     * expected to be inside a normal polygon. So an off-mesh connection is
     * "entered" from a normal polygon at one of its endpoints. This is the
     * polygon identified by the prev parameter.
     *
     * @param prev The reference of the polygon before the connection.
     * @param poly The reference of the off-mesh connection polygon.
     * @param start The start position of the off-mesh connection. [out]
     * @param end The end position of the off-mesh connection. [out]
     * @return The status flags for the operation.
     */
    public Status getOffMeshConnectionPolyEndPoints(Poly prev, Poly poly, Vector3f start, Vector3f end) {
        long prevRef = Poly.getCPtr(prev);
        long polyRef = Poly.getCPtr(poly);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(start);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(end);
        return new Status(RecastJNI.dtNavMesh_getOffMeshConnectionPolyEndPoints(swigCPtr, this, prevRef, polyRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos)));
    }

    /**
     * Gets the specified off-mesh connection.
     *
     * @param poly The polygon reference of the off-mesh connection.
     * @return The specified off-mesh connection, or null if the polygon
     * reference is not valid.
     */
    public OffMeshConnection getOffMeshConnection(Poly poly) {
        long ref = Poly.getCPtr(poly);
        long cPtr = RecastJNI.dtNavMesh_getOffMeshConnectionByRef(swigCPtr, this, ref);
        return (cPtr == 0) ? null : new OffMeshConnection(cPtr, false);
    }

    /**
     * Sets the user defined flags for the specified polygon.
     *
     * @param ref The polygon reference.
     * @param flags The new flags for the polygon.
     * @return The status flags for the operation.
     */
    public Status setPolyFlags(long ref, int flags) {
        long status = RecastJNI.dtNavMesh_setPolyFlags(swigCPtr, this, ref, flags);
        return (status == 0) ? null : new Status(status);
    }

    /**
     * Gets the user defined flags for the specified polygon.
     *
     * @param poly The polygon reference.
     * @param resultFlags The polygon flags.
     * @return The status flags for the operation.
     */
    public Status getPolyFlags(Poly poly, Short resultFlags) {
        long ref = Poly.getCPtr(poly);
        return new Status(RecastJNI.dtNavMesh_getPolyFlags(swigCPtr, this, ref, resultFlags));
    }

    /**
     * Sets the user defined area for the specified polygon.
     *
     * @param ref The polygon reference.
     * @param area The new area id for the polygon. [Limit: less than MAX_AREAS]
     * @return The status flags for the operation.
     */
    public Status setPolyArea(long ref, short area) {
        long status = RecastJNI.dtNavMesh_setPolyArea(swigCPtr, this, ref, area);
        return (status == 0) ? null : new Status(status);
    }

    /**
     * Gets the user defined area for the specified polygon.
     *
     * @param poly The polygon reference.
     * @param resultArea The area id for the polygon. [out]
     * @return The status flags for the operation.
     */
    public Status getPolyArea(Poly poly, Character resultArea) {
        long ref = Poly.getCPtr(poly);
        long status = RecastJNI.dtNavMesh_getPolyArea(swigCPtr, this, ref, resultArea);
        return (status == 0) ? null : new Status(status);
    }

    /**
     * Gets the size of the buffer required by storeTileState to store the
     * specified tile's state.
     *
     * @param tile The tile.
     * @return The size of the buffer required to store the state.
     */
    public int getTileStateSize(MeshTile tile) {
        return RecastJNI.dtNavMesh_getTileStateSize(swigCPtr, this, MeshTile.getCPtr(tile), tile);
    }

    /**
     * - doesn't work
     *
     * Stores the non-structural state of the tile in the specified buffer.
     *
     * Tile state includes non-structural data such as polygon flags, area ids,
     * etc.
     *
     * Note: The state data is only valid until the tile reference changes.
     *
     * @param tile The tile.
     * @param data The buffer to store the tile's state in.
     * @param maxDataSize The size of the data buffer. [Limit: >=
     * getTileStateSize]
     * @return The status flags for the operation.
     */
    public Status storeTileState(MeshTile tile, char[] data, int maxDataSize) {
        SWIGTYPE_p_unsigned_char data1 = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        long status = RecastJNI.dtNavMesh_storeTileState(swigCPtr, this, MeshTile.getCPtr(tile), tile, SWIGTYPE_p_unsigned_char.getCPtr(data1), maxDataSize);
        //data = Converter.convertToChars(data1, maxDataSize);
        return (status == 0) ? null : new Status(status);
    }

    /**
     * Restores the state of the tile.
     *
     * Tile state includes non-structural data such as polygon flags, area ids,
     * etc.
     *
     * @param tile Restores the state of the tile.
     * @param data The new state. (Obtained from storeTileState.)
     * @param maxDataSize The size of the state within the data buffer.
     * @return The status flags for the operation.
     */
    public Status restoreTileState(MeshTile tile, char[] data, int maxDataSize) {
        SWIGTYPE_p_unsigned_char data1 = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        long status = RecastJNI.dtNavMesh_restoreTileState(swigCPtr, this, MeshTile.getCPtr(tile), tile, SWIGTYPE_p_unsigned_char.getCPtr(data1), maxDataSize);
        return (status == 0) ? null : new Status(status);
    }

    /**
     * Derives a standard polygon reference. Note: This function is generally
     * meant for internal use only.
     *
     * @param salt The tile's salt value.
     * @param it The index of the tile.
     * @param ip The index of the polygon within the tile.
     * @return
     */
    public long encodePoly(long salt, long it, long ip) {
        return RecastJNI.dtNavMesh_encodePolyId(swigCPtr, this, salt, it, ip);
    }

    /**
     * Decodes a standard polygon reference.
     *
     * Note: This function is generally meant for internal use only.
     *
     * @param poly The polygon reference to decode.
     * @param salt The tile's salt value.
     * @param it The index of the tile.
     * @param ip The index of the polygon within the tile.
     */
    public void decodePoly(Poly poly, SWIGTYPE_p_unsigned_int salt, SWIGTYPE_p_unsigned_int it, SWIGTYPE_p_unsigned_int ip) {
        long ref = Poly.getCPtr(poly);
        RecastJNI.dtNavMesh_decodePolyId(swigCPtr, this, ref, SWIGTYPE_p_unsigned_int.getCPtr(salt), SWIGTYPE_p_unsigned_int.getCPtr(it), SWIGTYPE_p_unsigned_int.getCPtr(ip));
    }

    /**
     * Extracts a tile's salt value from the specified polygon reference.
     *
     * Note: This function is generally meant for internal use only.
     *
     * @param poly The polygon reference.
     * @return
     */
    public long decodePolySalt(Poly poly) {
        long ref = Poly.getCPtr(poly);
        return RecastJNI.dtNavMesh_decodePolyIdSalt(swigCPtr, this, ref);
    }

    /**
     * Extracts the tile's index from the specified polygon reference.
     *
     * Note: This function is generally meant for internal use only.
     *
     * @param poly The polygon reference.
     * @return
     */
    public long decodePolyTile(Poly poly) {
        long ref = Poly.getCPtr(poly);
        return RecastJNI.dtNavMesh_decodePolyIdTile(swigCPtr, this, ref);
    }

    /**
     * Extracts the polygon's index (within its tile) from the specified polygon
     * reference.
     *
     * Note: This function is generally meant for internal use only.
     *
     * @param poly The polygon reference.
     *
     * @return
     */
    public long decodePolyPoly(Poly poly) {
        long ref = Poly.getCPtr(poly);
        return RecastJNI.dtNavMesh_decodePolyIdPoly(swigCPtr, this, ref);
    }

    public boolean isAllocationSuccessful() {
        return swigCPtr != 0;
    }
} public class NavMeshCreateParams {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NavMeshCreateParams() {
        this(RecastJNI.new_dtNavMeshCreateParams(), true);
    }

    protected NavMeshCreateParams(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NavMeshCreateParams obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtNavMeshCreateParams(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * Get data from poly mesh that are needed to create params for navigation
     * mesh.
     *
     * @param polyMesh
     */
    public void getData(PolyMesh polyMesh) {
        setVertices(polyMesh.getVertices());
        setVerticesCount(polyMesh.getNumberOfVertices());
        setPolygons(polyMesh.getPolygons());
        setPolygonAreas(polyMesh.getAreas());
        setPolygonFlags(polyMesh.getFlags());
        setPolygonCount(polyMesh.getNumberOfPolygons());
        setNumberOfVerticesPerPolygon(polyMesh.getNumberOfVerticesPerPolygon());
        setMaxBounds(polyMesh.getMaxBounds());
        setMinBounds(polyMesh.getMinBounds());
    }

    /**
     * Get data from poly mesh detail that are needed to create params for
     * navigation mesh.
     *
     * @param detailMesh
     */
    public void getData(PolyMeshDetail detailMesh) {
        setDetailMeshes(detailMesh.getMeshes());
        setDetailVertices(detailMesh.getVertices());
        setDetailVerticesCount(detailMesh.getNumberOfVertices());
        setDetailTriangles(detailMesh.getTriangles());
        setDetailTriangleCount(detailMesh.getNumberOfTriangles());
    }

    /**
     * Get data from config that are needed to create params for navigation
     * mesh.
     *
     * @param config
     */
    public void getData(Config config) {
        setWalkableHeight(config.getWalkableHeight() * config.getCellHeight());
        setWalkableClimb(config.getWalkableClimb() * config.getCellHeight());
        setWalkableRadius(config.getWalkableRadius() * config.getCellSize());
        setCellHeight(config.getCellHeight());
        setCellSize(config.getCellSize());
    }

    /**
     * Updates the number of vertices and verticesCount.
     *
     * @param vertices The polygon mesh vertices.
     */
    public void setVertices(Vector3f[] vertices) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(vertices);
        RecastJNI.dtNavMeshCreateParams_verts_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The polygon mesh vertices.
     */
    public Vector3f[] getVertices() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_verts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, getVerticesCount());
    }

    /**
     *
     * @param value The number vertices in the polygon mesh. [Limit: >= 3].
     */
    public void setVerticesCount(int value) {
        RecastJNI.dtNavMeshCreateParams_vertCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number vertices in the polygon mesh. [Limit: >= 3].
     */
    public int getVerticesCount() {
        return RecastJNI.dtNavMeshCreateParams_vertCount_get(swigCPtr, this);
    }

    /**
     *
     * @param polygons The polygon data.
     */
    public void setPolygons(short[] polygons) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(polygons);
        RecastJNI.dtNavMeshCreateParams_polys_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The polygon data.
     */
    public short[] getPolygons() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_polys_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getPolygonCount() * 2 * getNumberOfVerticesPerPolygon());
    }

    /**
     *
     * @param polygonFlags The user defined flags assigned to each polygon.
     */
    public void setPolygonFlags(short[] polygonFlags) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(polygonFlags);
        RecastJNI.dtNavMeshCreateParams_polyFlags_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The user defined flags assigned to each polygon.
     */
    public short[] getPolygonFlags() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_polyFlags_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getPolygonCount());
    }

    /**
     *
     * @param polygonAreas The user defined area ids assigned to each polygon.
     */
    public void setPolygonAreas(char[] polygonAreas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(polygonAreas);
        RecastJNI.dtNavMeshCreateParams_polyAreas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return The user defined area ids assigned to each polygon.
     */
    public char[] getPolygonAreas() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_polyAreas_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getPolygonCount());
    }

    /**
     *
     * @param value Number of polygons in the mesh. [Limit: >= 1].
     */
    public void setPolygonCount(int value) {
        RecastJNI.dtNavMeshCreateParams_polyCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Number of polygons in the mesh. [Limit: >= 1].
     */
    public int getPolygonCount() {
        return RecastJNI.dtNavMeshCreateParams_polyCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value Number maximum number of vertices per polygon. [Limit: >=
     * 3].
     */
    public void setNumberOfVerticesPerPolygon(int value) {
        RecastJNI.dtNavMeshCreateParams_nvp_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Number maximum number of vertices per polygon. [Limit: >= 3].
     */
    public int getNumberOfVerticesPerPolygon() {
        return RecastJNI.dtNavMeshCreateParams_nvp_get(swigCPtr, this);
    }

    /**
     *
     * @param detailMeshes The height detail sub-mesh data.
     */
    public void setDetailMeshes(int[] detailMeshes) {
        SWIGTYPE_p_unsigned_int value = Converter.convertToSWIGTYPE_p_unsigned_int(detailMeshes);
        RecastJNI.dtNavMeshCreateParams_detailMeshes_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    /**
     *
     * @return The height detail sub-mesh data.
     */
    public int[] getDetailMeshes() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_detailMeshes_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToInts(cPtr, getPolygonCount() * 4);
    }

    /**
     *
     * @param detailVertices The detail mesh vertices.
     */
    public void setDetailVertices(Vector3f[] detailVertices) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(detailVertices);
        RecastJNI.dtNavMeshCreateParams_detailVerts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The detail mesh vertices.
     */
    public Vector3f[] getDetailVertices() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_detailVerts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, getDetailVerticesCount());
    }

    /**
     *
     * @param value The number of vertices in the detail mesh.
     */
    public void setDetailVerticesCount(int value) {
        RecastJNI.dtNavMeshCreateParams_detailVertsCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices in the detail mesh.
     */
    public int getDetailVerticesCount() {
        return RecastJNI.dtNavMeshCreateParams_detailVertsCount_get(swigCPtr, this);
    }

    /**
     *
     * @param detailTriangles The detail mesh triangles.
     */
    public void setDetailTriangles(char[] detailTriangles) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(detailTriangles);
        RecastJNI.dtNavMeshCreateParams_detailTris_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return The detail mesh triangles.
     */
    public char[] getDetailTriangles() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_detailTris_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getDetailTriangleCount() * 4);
    }

    /**
     *
     * @param value The number of triangles in the detail mesh.
     */
    public void setDetailTriangleCount(int value) {
        RecastJNI.dtNavMeshCreateParams_detailTriCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of triangles in the detail mesh.
     */
    public int getDetailTriangleCount() {
        return RecastJNI.dtNavMeshCreateParams_detailTriCount_get(swigCPtr, this);
    }

    /**
     *
     * @param connectionVertices Off-mesh connection vertices. [(ax, ay, az, bx,
     * by, bz)]
     */
    public void setOffMeshConnectionVertices(Vector3f[] connectionVertices) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(connectionVertices);
        RecastJNI.dtNavMeshCreateParams_offMeshConVerts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return Off-mesh connection vertices. [(ax, ay, az, bx, by, bz)]
     */
    public Vector3f[] getOffMeshConnectionVertices() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConVerts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, getOffMeshConnectionCount() * 2);
    }

    /**
     *
     * @param radii Off-mesh connection radii.
     */
    public void setOffMeshConnectionRadii(float[] radii) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(radii);
        RecastJNI.dtNavMeshCreateParams_offMeshConRad_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return Off-mesh connection radii.
     */
    public float[] getOffMeshConnectionRadii() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConRad_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToFloats(cPtr, getOffMeshConnectionCount());
    }

    /**
     *
     * @param connectionFlags User defined flags assigned to the off-mesh
     * connections.
     */
    public void setOffMeshConnectionFlags(short[] connectionFlags) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(connectionFlags);
        RecastJNI.dtNavMeshCreateParams_offMeshConFlags_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return User defined flags assigned to the off-mesh connections.
     */
    public short[] getOffMeshConnectionFlags() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConFlags_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getOffMeshConnectionCount());
    }

    /**
     *
     * @param connectionAreas User defined area ids assigned to the off-mesh
     * connections.
     */
    public void setOffMeshConnectionAreas(char[] connectionAreas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(connectionAreas);
        RecastJNI.dtNavMeshCreateParams_offMeshConAreas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return User defined area ids assigned to the off-mesh connections.
     */
    public char[] getOffMeshConnectionAreas() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConAreas_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getOffMeshConnectionCount());
    }

    /**
     * 0 = Travel only from endpoint A to endpoint B.
     *
     * DT_OFFMESH_CON_BIDIR = Bidirectional travel.
     *
     * @param connectionDirections The permitted travel direction of the
     * off-mesh connections.
     */
    public void setOffMeshConnectionDirection(char[] connectionDirections) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(connectionDirections);
        RecastJNI.dtNavMeshCreateParams_offMeshConDir_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     * 0 = Travel only from endpoint A to endpoint B.
     *
     * DT_OFFMESH_CON_BIDIR = Bidirectional travel.
     *
     * @return The permitted travel direction of the off-mesh connections.
     */
    public char[] getOffMeshConnectionDirection() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConDir_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getOffMeshConnectionCount());
    }

    /**
     *
     * @param connectionUserIDs The user defined ids of the off-mesh connection.
     */
    public void setOffMeshConnectionUserID(int[] connectionUserIDs) {
        SWIGTYPE_p_unsigned_int value = Converter.convertToSWIGTYPE_p_unsigned_int(connectionUserIDs);
        RecastJNI.dtNavMeshCreateParams_offMeshConUserID_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    /**
     *
     * @return The user defined ids of the off-mesh connection.
     */
    public int[] getOffMeshConnectionUserID() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_offMeshConUserID_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToInts(cPtr, getOffMeshConnectionCount());
    }

    /**
     *
     * @param value The number of off-mesh connections. [Limit: >= 0].
     */
    public void setOffMeshConnectionCount(int value) {
        RecastJNI.dtNavMeshCreateParams_offMeshConCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of off-mesh connections. [Limit: >= 0].
     */
    public int getOffMeshConnectionCount() {
        return RecastJNI.dtNavMeshCreateParams_offMeshConCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The user defined id of the tile.
     */
    public void setUserId(long value) {
        RecastJNI.dtNavMeshCreateParams_userId_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The user defined id of the tile.
     */
    public long getUserId() {
        return RecastJNI.dtNavMeshCreateParams_userId_get(swigCPtr, this);
    }

    /**
     *
     * @param value The tile's x-grid location within the multi-tile destination
     * mesh. (Along the x-axis.)
     */
    public void setTileX(int value) {
        RecastJNI.dtNavMeshCreateParams_tileX_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The tile's x-grid location within the multi-tile destination
     * mesh. (Along the x-axis.)
     */
    public int getTileX() {
        return RecastJNI.dtNavMeshCreateParams_tileX_get(swigCPtr, this);
    }

    /**
     *
     * @param value The tile's y-grid location within the multi-tile desitation
     * mesh. (Along the z-axis.)
     */
    public void setTileY(int value) {
        RecastJNI.dtNavMeshCreateParams_tileY_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The tile's y-grid location within the multi-tile desitation mesh.
     * (Along the z-axis.)
     */
    public int getTileY() {
        return RecastJNI.dtNavMeshCreateParams_tileY_get(swigCPtr, this);
    }

    /**
     *
     * @param value The tile's layer within the layered destination mesh.
     */
    public void setTileLayer(int value) {
        RecastJNI.dtNavMeshCreateParams_tileLayer_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The tile's layer within the layered destination mesh.
     */
    public int getTileLayer() {
        return RecastJNI.dtNavMeshCreateParams_tileLayer_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds of the tile
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.dtNavMeshCreateParams_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds of the tile
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_bmin_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds of the tile.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.dtNavMeshCreateParams_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds of the tile.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.dtNavMeshCreateParams_bmax_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The agent height.
     */
    public void setWalkableHeight(float value) {
        RecastJNI.dtNavMeshCreateParams_walkableHeight_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The agent height.
     */
    public float getWalkableHeight() {
        return RecastJNI.dtNavMeshCreateParams_walkableHeight_get(swigCPtr, this);
    }

    /**
     *
     * @param value The agent radius.
     */
    public void setWalkableRadius(float value) {
        RecastJNI.dtNavMeshCreateParams_walkableRadius_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The agent radius.
     */
    public float getWalkableRadius() {
        return RecastJNI.dtNavMeshCreateParams_walkableRadius_get(swigCPtr, this);
    }

    /**
     *
     * @param value The agent maximum traversable ledge. (Up/Down)
     */
    public void setWalkableClimb(float value) {
        RecastJNI.dtNavMeshCreateParams_walkableClimb_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The agent maximum traversable ledge. (Up/Down)
     */
    public float getWalkableClimb() {
        return RecastJNI.dtNavMeshCreateParams_walkableClimb_get(swigCPtr, this);
    }

    /**
     *
     * @param value The xz-plane cell size of the polygon mesh. [Limit: > 0]
     * [Unit: wu].
     */
    public void setCellSize(float value) {
        RecastJNI.dtNavMeshCreateParams_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The xz-plane cell size of the polygon mesh. [Limit: > 0] [Unit:
     * wu].
     */
    public float getCellSize() {
        return RecastJNI.dtNavMeshCreateParams_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The y-axis cell height of the polygon mesh. [Limit: > 0]
     * [Unit: wu].
     */
    public void setCellHeight(float value) {
        RecastJNI.dtNavMeshCreateParams_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The y-axis cell height of the polygon mesh. [Limit: > 0] [Unit:
     * wu].
     */
    public float getCellHeight() {
        return RecastJNI.dtNavMeshCreateParams_ch_get(swigCPtr, this);
    }

    /**
     * The BVTree is not normally needed for layered navigation meshes.
     *
     * @param value True if a bounding volume tree should be built for the tile.
     */
    public void setBuildBvTree(boolean value) {
        RecastJNI.dtNavMeshCreateParams_buildBvTree_set(swigCPtr, this, value);
    }

    /**
     * The BVTree is not normally needed for layered navigation meshes.
     *
     * @return True if a bounding volume tree should be built for the tile.
     */
    public boolean isBuildBvTree() {
        return RecastJNI.dtNavMeshCreateParams_buildBvTree_get(swigCPtr, this);
    }
} public class NavMeshParams {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NavMeshParams() {
        this(RecastJNI.new_dtNavMeshParams(), true);
    }

    protected NavMeshParams(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NavMeshParams obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtNavMeshParams(swigCPtr);
            }
            swigCPtr = 0;
        }
    }
    
    /**
     *
     * @param origin The world space origin of the navigation mesh's tile space.
     */
    public void setOrigin(Vector3f origin) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(origin);
        RecastJNI.dtNavMeshParams_orig_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The world space origin of the navigation mesh's tile space.
     */
    public Vector3f getOrigin() {
        long cPtr = RecastJNI.dtNavMeshParams_orig_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The width of each tile. (Along the x-axis.)
     */
    public void setTileWidth(float value) {
        RecastJNI.dtNavMeshParams_tileWidth_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of each tile. (Along the x-axis.)
     */
    public float getTileWidth() {
        return RecastJNI.dtNavMeshParams_tileWidth_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each tile. (Along the z-axis.)
     */
    public void setTileHeight(float value) {
        RecastJNI.dtNavMeshParams_tileHeight_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each tile. (Along the z-axis.)
     */
    public float getTileHeight() {
        return RecastJNI.dtNavMeshParams_tileHeight_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum number of tiles the navigation mesh can contain.
     */
    public void setMaxTiles(int value) {
        RecastJNI.dtNavMeshParams_maxTiles_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum number of tiles the navigation mesh can contain.
     */
    public int getMaxTiles() {
        return RecastJNI.dtNavMeshParams_maxTiles_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum number of polygons each tile can contain.
     */
    public void setMaxPolygons(int value) {
        RecastJNI.dtNavMeshParams_maxPolys_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum number of polygons each tile can contain.
     */
    public int getMaxPolygons() {
        return RecastJNI.dtNavMeshParams_maxPolys_get(swigCPtr, this);
    }
} public class NavMeshQuery {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NavMeshQuery() {
        swigCPtr = RecastJNI.dtAllocNavMeshQuery();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    public NavMeshQuery(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NavMeshQuery obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.dtFreeNavMeshQuery(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     * Initializes the query object. Must be the first function called after
     * construction, before other functions are used.
     *
     * This function can be used multiple times.
     *
     * @param nav Pointer to the NavMesh object to use for all queries.
     * @param maxNodes Maximum number of search nodes. [Limits: 0 less value
     * less or equal to 65536]
     * @return The status flags for the query.
     */
    public Status init(NavMesh nav, int maxNodes) {
        long status = RecastJNI.dtNavMeshQuery_init(swigCPtr, this, NavMesh.getCPtr(nav), nav, maxNodes);
        return new Status(status);
    }

    /**
     * Finds a path from the start polygon to the end polygon. If the end
     * polygon cannot be reached through the navigation graph, the last polygon
     * in the path will be the nearest the end polygon.
     *
     * If the path array is to small to hold the full result, it will be filled
     * as far as possible from the start polygon toward the end polygon.
     *
     * The start and end positions are used to calculate traversal costs. (The
     * y-values impact the result.)
     *
     * @param startPoly The refrence id of the start polygon.
     * @param endPoly The reference id of the end polygon
     * @param startPosition A position within the start polygon.
     * @param endPosition A position within the end polygon.
     * @param filter The polygon filter to apply to the query.
     * @param maxPath The maximum number of polygons the path array can hold.
     * [Limit: >= 1]
     * @return
     */
    public Status findPathStatus(Poly startPoly, Poly endPoly, Vector3f startPosition, Vector3f endPosition, QueryFilter filter, int maxPath) {
        long startRef = Poly.getCPtr(startPoly);
        long endRef = Poly.getCPtr(endPoly);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findPath(swigCPtr, this, startRef, endRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return new Status(status);
    }

    /**
     * Finds a path from the start polygon to the end polygon. If the end
     * polygon cannot be reached through the navigation graph, the last polygon
     * in the path will be the nearest the end polygon.
     *
     * If the path array is to small to hold the full result, it will be filled
     * as far as possible from the start polygon toward the end polygon.
     *
     * The start and end positions are used to calculate traversal costs. (The
     * y-values impact the result.)
     *
     * @param startPoly The refrence id of the start polygon.
     * @param endPoly The reference id of the end polygon
     * @param startPosition A position within the start polygon.
     * @param endPosition A position within the end polygon.
     * @param filter The polygon filter to apply to the query.
     * @param maxPath The maximum number of polygons the path array can hold.
     * [Limit: >= 1]
     * @return
     */
    public Poly[] findPath(Poly startPoly, Poly endPoly, Vector3f startPosition, Vector3f endPosition, QueryFilter filter, int maxPath) {
        long startRef = Poly.getCPtr(startPoly);
        long endRef = Poly.getCPtr(endPoly);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findPath(swigCPtr, this, startRef, endRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return Converter.convertToPolys(SWIGTYPE_p_unsigned_int.getCPtr(path), Converter.convertToInt(SWIGTYPE_p_int.getCPtr(pathCount)));
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return The status flags for the query.
     */
    public Status findStraightPathStatus(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath, int options) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath, options);
        return new Status(status);
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return Points describing the straight path.
     */
    public Vector3f[] findStraightPath(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath, int options) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath, options);
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(straightPath), Converter.convertToInt(SWIGTYPE_p_int.getCPtr(straightPathCount)));
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return The reference id of the polygon that is being entered at each
     * point.
     */
    public Poly[] findStraightPathRefs(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath, int options) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath, options);
        return Converter.convertToPolys(straightPathRefs, straightPathCount);
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return Flags describing each point. (See: dtStraightPathFlags)
     */
    public char[] findStraightPathFlags(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath, int options) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_0(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath, options);
        return Converter.convertToChars(straightPathFlags, Converter.convertToInt(SWIGTYPE_p_int.getCPtr(straightPathCount)));
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return The status flags for the query.
     */
    public Status findStraightPathStatus(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath);
        return new Status(status);
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return Points describing the straight path.
     */
    public Vector3f[] findStraightPath(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath);
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(straightPath), Converter.convertToInt(SWIGTYPE_p_int.getCPtr(straightPathCount)));
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return The reference id of the polygon that is being entered at each
     * point.
     */
    public Poly[] findStraightPathRefs(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath);
        return Converter.convertToPolys(straightPathRefs, straightPathCount);
    }

    /**
     * Finds the straight path from the start to the end position within the
     * polygon corridor.
     *
     * This method peforms what is often called 'string pulling'.
     *
     * The start position is clamped to the first polygon in the path, and the
     * end position is clamped to the last. So the start and end positions
     * should normally be within or very near the first and last polygons
     * respectively.
     *
     * The returned polygon references represent the reference id of the polygon
     * that is entered at the associated path position. The reference id
     * associated with the end point will always be zero. This allows, for
     * example, matching off-mesh link points to their representative polygons.
     *
     * If the provided result buffers are too small for the entire result set,
     * they will be filled as far as possible from the start toward the end
     * position.
     *
     * @param startPosition Path start position.
     * @param endPosition Path end position.
     * @param path An array of polygon references that represent the path
     * corridor.
     * @param maxStraightPath The maximum number of points the straight path
     * arrays can hold. [Limit: > 0]
     * @param options Query options. (see: dtStraightPathOptions)
     * @return Flags describing each point. (See: dtStraightPathFlags)
     */
    public char[] findStraightPathFlags(Vector3f startPosition, Vector3f endPosition, Poly[] path, int maxStraightPath) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_unsigned_int paths = Converter.convertToSWIGTYPE_p_unsigned_int(path);
        int pathSize = path.length;
        SWIGTYPE_p_float straightPath = new FloatArray(3 * maxStraightPath).cast();
        SWIGTYPE_p_unsigned_char straightPathFlags = new UCharArray(maxStraightPath).cast();
        SWIGTYPE_p_unsigned_int straightPathRefs = new UIntArray(maxStraightPath).cast();
        SWIGTYPE_p_int straightPathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findStraightPath__SWIG_1(swigCPtr, this, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), SWIGTYPE_p_unsigned_int.getCPtr(paths), pathSize, SWIGTYPE_p_float.getCPtr(straightPath), SWIGTYPE_p_unsigned_char.getCPtr(straightPathFlags), SWIGTYPE_p_unsigned_int.getCPtr(straightPathRefs), SWIGTYPE_p_int.getCPtr(straightPathCount), maxStraightPath);
        return Converter.convertToChars(straightPathFlags, Converter.convertToInt(SWIGTYPE_p_int.getCPtr(straightPathCount)));
    }

    /**
     * Intializes a sliced path query.
     *
     * Warning: Calling any non-slice methods before calling
     * finalizeSlicedFindPath() or finalizeSlicedFindPathPartial() may result in
     * corrupted data! The filter pointer is stored and used for the duration of
     * the sliced path query.
     *
     * @param start The refrence id of the start polygon.
     * @param end The reference id of the end polygon.
     * @param startPosition A position within the start polygon.
     * @param endPosition A position within the end polygon.
     * @param filter The polygon filter to apply to the query.
     * @return The status flags for the query.
     */
    public Status initSlicedFindPath(Poly start, Poly end, Vector3f startPosition, Vector3f endPosition, QueryFilter filter) {
        long startRef = Poly.getCPtr(start);
        long endRef = Poly.getCPtr(end);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        long status = RecastJNI.dtNavMeshQuery_initSlicedFindPath(swigCPtr, this, startRef, endRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter);
        return new Status(status);
    }

    /**
     * Updates an in-progress sliced path query.
     *
     * @param maxIter The maximum number of iterations to perform.
     * @return The status flags for the query.
     */
    public Status updateSlicedFindPath(int maxIter) {
        SWIGTYPE_p_int doneIters = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_updateSlicedFindPath(swigCPtr, this, maxIter, SWIGTYPE_p_int.getCPtr(doneIters));
        return new Status(status);
    }

    /**
     * Finalizes and returns the status of a sliced path query.
     *
     * @param maxPath The max number of polygons the path array can hold.
     * @return The status flags for the query.
     */
    public Status finalizeSlicedFindPathStatus(int maxPath) {
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_finalizeSlicedFindPath(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return new Status(status);
    }

    /**
     * Finalizes and returns the results of a sliced path query.
     *
     * @param maxPath The max number of polygons the path array can hold.
     * @return An ordered list of polygon references representing the path.
     */
    public Poly[] finalizeSlicedFindPath(int maxPath) {
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_finalizeSlicedFindPath(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return Converter.convertToPolys(SWIGTYPE_p_unsigned_int.getCPtr(path), Converter.convertToInt(SWIGTYPE_p_int.getCPtr(pathCount)));
    }

    /**
     * Finalizes and returns the results of an incomplete sliced path query,
     * returning the path to the furthest polygon on the existing path that was
     * visited during the search.
     *
     * @param polys An array of polygon references for the existing path.
     * @param maxPath The max number of polygons the path array can hold.
     * [Limit: >= 1]
     * @return The status flags for the query.
     */
    public Status finalizeSlicedFindPathPartialStatus(Poly[] polys, int maxPath) {
        SWIGTYPE_p_unsigned_int existing = Converter.convertToSWIGTYPE_p_unsigned_int(polys);
        int existingSize = polys.length;
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_finalizeSlicedFindPathPartial(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(existing), existingSize, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return new Status(status);
    }

    /**
     * Finalizes and returns the results of an incomplete sliced path query,
     * returning the path to the furthest polygon on the existing path that was
     * visited during the search.
     *
     * @param polys An array of polygon references for the existing path.
     * @param maxPath The max number of polygons the path array can hold.
     * [Limit: >= 1]
     * @return An ordered list of polygon references representing the path.
     * (Start to end.)
     */
    public Poly[] finalizeSlicedFindPathPartial(Poly[] polys, int maxPath) {
        SWIGTYPE_p_unsigned_int existing = Converter.convertToSWIGTYPE_p_unsigned_int(polys);
        int existingSize = polys.length;
        SWIGTYPE_p_unsigned_int path = new UIntArray(maxPath).cast();
        SWIGTYPE_p_int pathCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_finalizeSlicedFindPathPartial(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(existing), existingSize, SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
        return Converter.convertToPolys(existing, pathCount);
    }

    /**
     * Finds the polygons along the navigation graph that touch the specified
     * circle.
     *
     * The order of the result set is from least to highest cost to reach the
     * polygon.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * If a polygon is not found via the graph search, even if it intersects the
     * search circle, it will not be included in the result set. For example:
     *
     * polyA is the start polygon. polyB shares an edge with polyA. (Is
     * adjacent.) polyC shares an edge with polyB, but not with polyA Even if
     * the search circle overlaps polyC, it will not be included in the result
     * set unless polyB is also in the set.
     *
     * The value of the center point is used as the start position for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are to small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param startPosition The center of the search circle.
     * @param radius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The status flags for the query.
     */
    public Status findPolysAroundCircleStatus(Poly start, Vector3f startPosition, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findPolysAroundCircle(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return new Status(status);
    }

    /**
     * Finds the polygons along the navigation graph that touch the specified
     * circle.
     *
     * The order of the result set is from least to highest cost to reach the
     * polygon.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * If a polygon is not found via the graph search, even if it intersects the
     * search circle, it will not be included in the result set. For example:
     *
     * polyA is the start polygon. polyB shares an edge with polyA. (Is
     * adjacent.) polyC shares an edge with polyB, but not with polyA Even if
     * the search circle overlaps polyC, it will not be included in the result
     * set unless polyB is also in the set.
     *
     * The value of the center point is used as the start position for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are to small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param startPosition The center of the search circle.
     * @param radius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the polygons touched by the circle.
     */
    public Poly[] findPolysAroundCircle(Poly start, Vector3f startPosition, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findPolysAroundCircle(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultRef, resultCount);
    }

    /**
     * Finds the polygons along the navigation graph that touch the specified
     * circle.
     *
     * The order of the result set is from least to highest cost to reach the
     * polygon.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * If a polygon is not found via the graph search, even if it intersects the
     * search circle, it will not be included in the result set. For example:
     *
     * polyA is the start polygon. polyB shares an edge with polyA. (Is
     * adjacent.) polyC shares an edge with polyB, but not with polyA Even if
     * the search circle overlaps polyC, it will not be included in the result
     * set unless polyB is also in the set.
     *
     * The value of the center point is used as the start position for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are to small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param startPosition The center of the search circle.
     * @param radius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the parent polygons for each result.
     */
    public Poly[] findPolysAroundCircleParentRef(Poly start, Vector3f startPosition, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findPolysAroundCircle(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultParent, maxResult);
    }

    /**
     * Finds the polygons along the naviation graph that touch the specified
     * convex polygon.
     *
     * The order of the result set is from least to highest cost.
     *
     * At least one result array must be provided.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * The same intersection test restrictions that apply to
     * findPolysAroundCircle() method apply to this method.
     *
     * The 3D centroid of the search polygon is used as the start position for
     * cost calculations.
     *
     * Intersection tests occur in 2D. All polygons are projected onto the
     * xz-plane. So the y-values of the vertices do not effect intersection
     * tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param vertices The vertices describing the convex polygon. (CCW)
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The status flags for the query.
     */
    public Status findPolysAroundShapeStatus(Poly start, Vector3f[] vertices, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float verts = Converter.convertToSWIGTYPE_p_float(vertices);
        int nverts = vertices.length;
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findPolysAroundShape(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(verts), nverts, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return new Status(status);
    }

    /**
     * Finds the polygons along the naviation graph that touch the specified
     * convex polygon.
     *
     * The order of the result set is from least to highest cost.
     *
     * At least one result array must be provided.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * The same intersection test restrictions that apply to
     * findPolysAroundCircle() method apply to this method.
     *
     * The 3D centroid of the search polygon is used as the start position for
     * cost calculations.
     *
     * Intersection tests occur in 2D. All polygons are projected onto the
     * xz-plane. So the y-values of the vertices do not effect intersection
     * tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param vertices The vertices describing the convex polygon. (CCW)
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the polygons touched by the search polygon.
     */
    public Poly[] findPolysAroundShape(Poly start, Vector3f[] vertices, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float verts = Converter.convertToSWIGTYPE_p_float(vertices);
        int nverts = vertices.length;
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findPolysAroundShape(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(verts), nverts, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultRef, resultCount);
    }

    /**
     * Finds the polygons along the naviation graph that touch the specified
     * convex polygon.
     *
     * The order of the result set is from least to highest cost.
     *
     * At least one result array must be provided.
     *
     * A common use case for this method is to perform Dijkstra searches.
     * Candidate polygons are found by searching the graph beginning at the
     * start polygon.
     *
     * The same intersection test restrictions that apply to
     * findPolysAroundCircle() method apply to this method.
     *
     * The 3D centroid of the search polygon is used as the start position for
     * cost calculations.
     *
     * Intersection tests occur in 2D. All polygons are projected onto the
     * xz-plane. So the y-values of the vertices do not effect intersection
     * tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param vertices The vertices describing the convex polygon. (CCW)
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the parent polygons for each result.
     */
    public Poly[] findPolysAroundShapeParentRef(Poly start, Vector3f[] vertices, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float verts = Converter.convertToSWIGTYPE_p_float(vertices);
        int nverts = vertices.length;
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_float resultCost = new FloatArray(1).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findPolysAroundShape(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(verts), nverts, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_float.getCPtr(resultCost), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultParent, resultCount);
    }

    /**
     * Finds the polygon nearest to the specified center point.
     *
     * Note: If the search box does not intersect any polygons the search will
     * return DT_SUCCESS, but nearestRef will be zero. So if in doubt, check
     * nearestRef before using nearestPt.
     *
     * Warning: This function is not suitable for large area searches. If the
     * search extents overlaps more than 128 polygons it may return an invalid
     * result.
     *
     * @param center The center of the search box.
     * @param extent The search distance along each axis.
     * @param filter The polygon filter to apply to the query.
     * @return The status flags for the query.
     *
     */
    public Status findNearestPolyStatus(Vector3f center, Vector3f extent, QueryFilter filter) {
        SWIGTYPE_p_float cen = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float extents = Converter.convertToSWIGTYPE_p_float(extent);
        SWIGTYPE_p_unsigned_int nearestRef = new UIntArray(1).cast();
        SWIGTYPE_p_float nearestPt = new FloatArray(3).cast();
        long status = RecastJNI.dtNavMeshQuery_findNearestPoly(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cen), SWIGTYPE_p_float.getCPtr(extents), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(nearestRef), SWIGTYPE_p_float.getCPtr(nearestPt));
        return new Status(status);
    }

    /**
     * Finds the polygon nearest to the specified center point.
     *
     * Note: If the search box does not intersect any polygons the search will
     * return DT_SUCCESS, but nearestRef will be zero. So if in doubt, check
     * nearestRef before using nearestPt.
     *
     * Warning: This function is not suitable for large area searches. If the
     * search extents overlaps more than 128 polygons it may return an invalid
     * result.
     *
     * @param center The center of the search box.
     * @param extent The search distance along each axis.
     * @param filter The polygon filter to apply to the query.
     * @return The reference id of the nearest polygon.
     *
     */
    public Poly findNearestPoly(Vector3f center, Vector3f extent, QueryFilter filter) {
        SWIGTYPE_p_float cen = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float extents = Converter.convertToSWIGTYPE_p_float(extent);
        SWIGTYPE_p_unsigned_int nearestRef = new UIntArray(1).cast();
        SWIGTYPE_p_float nearestPt = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_findNearestPoly(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cen), SWIGTYPE_p_float.getCPtr(extents), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(nearestRef), SWIGTYPE_p_float.getCPtr(nearestPt));
        return new Poly(SWIGTYPE_p_unsigned_int.getCPtr(nearestRef), false);
    }

    /**
     * Finds the polygon nearest to the specified center point.
     *
     * Note: If the search box does not intersect any polygons the search will
     * return DT_SUCCESS, but nearestRef will be zero. So if in doubt, check
     * nearestRef before using nearestPt.
     *
     * Warning: This function is not suitable for large area searches. If the
     * search extents overlaps more than 128 polygons it may return an invalid
     * result.
     *
     * @param center The center of the search box.
     * @param extent The search distance along each axis.
     * @param filter The polygon filter to apply to the query.
     * @return The nearest point on the polygon.
     *
     */
    public Vector3f findNearestPolyPoint(Vector3f center, Vector3f extent, QueryFilter filter) {
        SWIGTYPE_p_float cen = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float extents = Converter.convertToSWIGTYPE_p_float(extent);
        SWIGTYPE_p_unsigned_int nearestRef = new UIntArray(1).cast();
        SWIGTYPE_p_float nearestPt = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_findNearestPoly(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cen), SWIGTYPE_p_float.getCPtr(extents), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(nearestRef), SWIGTYPE_p_float.getCPtr(nearestPt));
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(nearestPt));
    }

    /**
     * Finds polygons that overlap the search box. If no polygons are found, the
     * function will return DT_SUCCESS with a polyCount of zero.
     *
     * If polys is too small to hold the entire result set, then the array will
     * be filled to capacity. The method of choosing which polygons from the
     * full set are included in the partial result set is undefined.
     *
     * @param center The center of the search box.
     * @param extent The search distance along each axis.
     * @param filter The polygon filter to apply to the query.
     * @param maxPolys The maximum number of polygons the search result can
     * hold.
     * @return The status flags for the query.
     */
    public Status queryPolygonsStatus(Vector3f center, Vector3f extent, QueryFilter filter, int maxPolys) {
        SWIGTYPE_p_float cen = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float extents = Converter.convertToSWIGTYPE_p_float(extent);
        SWIGTYPE_p_unsigned_int polys = new UIntArray(maxPolys).cast();
        SWIGTYPE_p_int polyCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_queryPolygons(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cen), SWIGTYPE_p_float.getCPtr(extents), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(polys), SWIGTYPE_p_int.getCPtr(polyCount), maxPolys);
        return new Status(status);
    }

    /**
     * Finds polygons that overlap the search box. If no polygons are found, the
     * function will return DT_SUCCESS with a polyCount of zero.
     *
     * If polys is too small to hold the entire result set, then the array will
     * be filled to capacity. The method of choosing which polygons from the
     * full set are included in the partial result set is undefined.
     *
     * @param center The center of the search box.
     * @param extent The search distance along each axis.
     * @param filter The polygon filter to apply to the query.
     * @param maxPolys The maximum number of polygons the search result can
     * hold.
     * @return The reference ids of the polygons that overlap the query box.
     */
    public Poly[] queryPolygons(Vector3f center, Vector3f extent, QueryFilter filter, int maxPolys) {
        SWIGTYPE_p_float cen = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float extents = Converter.convertToSWIGTYPE_p_float(extent);
        SWIGTYPE_p_unsigned_int polys = new UIntArray(maxPolys).cast();
        SWIGTYPE_p_int polyCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_queryPolygons(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cen), SWIGTYPE_p_float.getCPtr(extents), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(polys), SWIGTYPE_p_int.getCPtr(polyCount), maxPolys);
        return Converter.convertToPolys(polys, polyCount);
    }

    /**
     * Finds the non-overlapping navigation polygons in the local neighbourhood
     * around the center position. This method is optimized for a small search
     * radius and small number of result polygons.
     *
     * Candidate polygons are found by searching the navigation graph beginning
     * at the start polygon.
     *
     * The same intersection test restrictions that apply to the
     * findPolysAroundCircle mehtod applies to this method.
     *
     * The value of the center point is used as the start point for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param center The center of the query circle.
     * @param radius The radius of the query circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The status flags for the query.
     */
    public Status findLocalNeighbourhoodStatus(Poly start, Vector3f center, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_findLocalNeighbourhood(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return new Status(status);
    }

    /**
     * Finds the non-overlapping navigation polygons in the local neighbourhood
     * around the center position. This method is optimized for a small search
     * radius and small number of result polygons.
     *
     * Candidate polygons are found by searching the navigation graph beginning
     * at the start polygon.
     *
     * The same intersection test restrictions that apply to the
     * findPolysAroundCircle mehtod applies to this method.
     *
     * The value of the center point is used as the start point for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param center The center of the query circle.
     * @param radius The radius of the query circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the polygons touched by the circle.
     */
    public Poly[] findLocalNeighbourhood(Poly start, Vector3f center, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findLocalNeighbourhood(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultRef, resultCount);
    }

    /**
     * Finds the non-overlapping navigation polygons in the local neighbourhood
     * around the center position. This method is optimized for a small search
     * radius and small number of result polygons.
     *
     * Candidate polygons are found by searching the navigation graph beginning
     * at the start polygon.
     *
     * The same intersection test restrictions that apply to the
     * findPolysAroundCircle mehtod applies to this method.
     *
     * The value of the center point is used as the start point for cost
     * calculations. It is not projected onto the surface of the mesh, so its
     * y-value will effect the costs.
     *
     * Intersection tests occur in 2D. All polygons and the search circle are
     * projected onto the xz-plane. So the y-value of the center point does not
     * effect intersection tests.
     *
     * If the result arrays are is too small to hold the entire result set, they
     * will be filled to capacity.
     *
     * @param start The reference id of the polygon where the search starts.
     * @param center The center of the query circle.
     * @param radius The radius of the query circle.
     * @param filter The polygon filter to apply to the query.
     * @param maxResult The maximum number of polygons the result arrays can
     * hold.
     * @return The reference ids of the parent polygons for each result.
     */
    public Poly[] findLocalNeighbourhoodParentRef(Poly start, Vector3f center, float radius, QueryFilter filter, int maxResult) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_unsigned_int resultRef = new UIntArray(maxResult).cast();
        SWIGTYPE_p_unsigned_int resultParent = new UIntArray(maxResult).cast();
        SWIGTYPE_p_int resultCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_findLocalNeighbourhood(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), radius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_unsigned_int.getCPtr(resultRef), SWIGTYPE_p_unsigned_int.getCPtr(resultParent), SWIGTYPE_p_int.getCPtr(resultCount), maxResult);
        return Converter.convertToPolys(resultParent, resultCount);
    }

    /**
     * Moves from the start to the end position constrained to the navigation
     * mesh.
     *
     * This method is optimized for small delta movement and a small number of
     * polygons. If used for too great a distance, the result set will form an
     * incomplete path.
     *
     * resultPos will equal the endPos if the end is reached. Otherwise the
     * closest reachable position will be returned.
     *
     * resultPos is not projected onto the surface of the navigation mesh. Use
     * getPolyHeight if this is needed.
     *
     * This method treats the end position in the same manner as the raycast
     * method. (As a 2D point.) See that method's documentation for details.
     *
     * If the visited array is too small to hold the entire result set, it will
     * be filled as far as possible from the start position toward the end
     * position.
     *
     * @param start The reference id of the start polygon.
     * @param startPosition A position of the mover within the start polygon.
     * @param endPosition The desired end position of the mover.
     * @param filter The polygon filter to apply to the query.
     * @param maxVisitedSize The maximum number of polygons the visited array
     * can hold.
     * @return The status flags for the query.
     */
    public Status moveAlongSurfaceStatus(Poly start, Vector3f startPosition, Vector3f endPosition, QueryFilter filter, int maxVisitedSize) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_float resultPos = new FloatArray(3).cast();
        SWIGTYPE_p_unsigned_int visited = new UIntArray(maxVisitedSize).cast();
        SWIGTYPE_p_int visitedCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_moveAlongSurface(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(resultPos), SWIGTYPE_p_unsigned_int.getCPtr(visited), SWIGTYPE_p_int.getCPtr(visitedCount), maxVisitedSize);
        return new Status(status);
    }

    /**
     * Moves from the start to the end position constrained to the navigation
     * mesh.
     *
     * This method is optimized for small delta movement and a small number of
     * polygons. If used for too great a distance, the result set will form an
     * incomplete path.
     *
     * resultPos will equal the endPos if the end is reached. Otherwise the
     * closest reachable position will be returned.
     *
     * resultPos is not projected onto the surface of the navigation mesh. Use
     * getPolyHeight if this is needed.
     *
     * This method treats the end position in the same manner as the raycast
     * method. (As a 2D point.) See that method's documentation for details.
     *
     * If the visited array is too small to hold the entire result set, it will
     * be filled as far as possible from the start position toward the end
     * position.
     *
     * @param start The reference id of the start polygon.
     * @param startPosition A position of the mover within the start polygon.
     * @param endPosition The desired end position of the mover.
     * @param filter The polygon filter to apply to the query.
     * @param maxVisitedSize The maximum number of polygons the visited array
     * can hold.
     * @return The result position of the mover.
     */
    public Vector3f moveAlongSurfaceResultPosition(Poly start, Vector3f startPosition, Vector3f endPosition, QueryFilter filter, int maxVisitedSize) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_float resultPos = new FloatArray(3).cast();
        SWIGTYPE_p_unsigned_int visited = new UIntArray(maxVisitedSize).cast();
        SWIGTYPE_p_int visitedCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_moveAlongSurface(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(resultPos), SWIGTYPE_p_unsigned_int.getCPtr(visited), SWIGTYPE_p_int.getCPtr(visitedCount), maxVisitedSize);
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(resultPos));
    }

    /**
     * Moves from the start to the end position constrained to the navigation
     * mesh.
     *
     * This method is optimized for small delta movement and a small number of
     * polygons. If used for too great a distance, the result set will form an
     * incomplete path.
     *
     * resultPos will equal the endPos if the end is reached. Otherwise the
     * closest reachable position will be returned.
     *
     * resultPos is not projected onto the surface of the navigation mesh. Use
     * getPolyHeight if this is needed.
     *
     * This method treats the end position in the same manner as the raycast
     * method. (As a 2D point.) See that method's documentation for details.
     *
     * If the visited array is too small to hold the entire result set, it will
     * be filled as far as possible from the start position toward the end
     * position.
     *
     * @param start The reference id of the start polygon.
     * @param startPosition A position of the mover within the start polygon.
     * @param endPosition The desired end position of the mover.
     * @param filter The polygon filter to apply to the query.
     * @param maxVisitedSize The maximum number of polygons the visited array
     * can hold.
     * @return The reference ids of the polygons visited during the move.
     */
    public Poly[] moveAlongSurfaceVisited(Poly start, Vector3f startPosition, Vector3f endPosition, QueryFilter filter, int maxVisitedSize) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        SWIGTYPE_p_float resultPos = new FloatArray(3).cast();
        SWIGTYPE_p_unsigned_int visited = new UIntArray(maxVisitedSize).cast();
        SWIGTYPE_p_int visitedCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_moveAlongSurface(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(resultPos), SWIGTYPE_p_unsigned_int.getCPtr(visited), SWIGTYPE_p_int.getCPtr(visitedCount), maxVisitedSize);
        return Converter.convertToPolys(visited, visitedCount);
    }
    /*
     * Not fixed, because I wanted to see if there is something similiar to it in jME already.
     public long raycast(long startRef, SWIGTYPE_p_float startPos, SWIGTYPE_p_float endPos, QueryFilter filter, SWIGTYPE_p_float t, SWIGTYPE_p_float hitNormal, SWIGTYPE_p_unsigned_int path, SWIGTYPE_p_int pathCount, int maxPath) {
     return RecastJNI.dtNavMeshQuery_raycast(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(t), SWIGTYPE_p_float.getCPtr(hitNormal), SWIGTYPE_p_unsigned_int.getCPtr(path), SWIGTYPE_p_int.getCPtr(pathCount), maxPath);
     }
     */

    /**
     * Finds the distance from the specified position to the nearest polygon
     * wall.
     *
     * @param start The reference id of the polygon containing center.
     * @param center The center of the search circle.
     * @param maxRadius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @return The status flags for the query.
     */
    public Status findDistanceToWallStatus(Poly start, Vector3f center, float maxRadius, QueryFilter filter) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float hitDist = new FloatArray(1).cast();
        SWIGTYPE_p_float hitPos = new FloatArray(3).cast();
        SWIGTYPE_p_float hitNormal = new FloatArray(3).cast();
        long status = RecastJNI.dtNavMeshQuery_findDistanceToWall(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), maxRadius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(hitDist), SWIGTYPE_p_float.getCPtr(hitPos), SWIGTYPE_p_float.getCPtr(hitNormal));
        return new Status(status);
    }

    /**
     * Finds the distance from the specified position to the nearest polygon
     * wall.
     *
     * @param start The reference id of the polygon containing center.
     * @param center The center of the search circle.
     * @param maxRadius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @return The distance to the nearest wall from center.
     */
    public float findDistanceToWall(Poly start, Vector3f center, float maxRadius, QueryFilter filter) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float hitDist = new FloatArray(1).cast();
        SWIGTYPE_p_float hitPos = new FloatArray(3).cast();
        SWIGTYPE_p_float hitNormal = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_findDistanceToWall(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), maxRadius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(hitDist), SWIGTYPE_p_float.getCPtr(hitPos), SWIGTYPE_p_float.getCPtr(hitNormal));
        return Converter.convertToFloat(SWIGTYPE_p_float.getCPtr(hitDist));
    }

    /**
     * Finds the distance from the specified position to the nearest polygon
     * wall.
     *
     * @param start The reference id of the polygon containing center.
     * @param center The center of the search circle.
     * @param maxRadius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @return The nearest position on the wall that was hit. It will equal the
     * search radius if there is no wall within the radius.
     */
    public Vector3f findDistancePositionToWall(Poly start, Vector3f center, float maxRadius, QueryFilter filter) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float hitDist = new FloatArray(1).cast();
        SWIGTYPE_p_float hitPos = new FloatArray(3).cast();
        SWIGTYPE_p_float hitNormal = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_findDistanceToWall(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), maxRadius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(hitDist), SWIGTYPE_p_float.getCPtr(hitPos), SWIGTYPE_p_float.getCPtr(hitNormal));
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(hitPos));
    }

    /**
     * Finds the distance from the specified position to the nearest polygon
     * wall.
     *
     * @param start The reference id of the polygon containing center.
     * @param center The center of the search circle.
     * @param maxRadius The radius of the search circle.
     * @param filter The polygon filter to apply to the query.
     * @return The normalized ray formed from the wall point to the source
     * point.
     */
    public Vector3f findDistanceNormalToWall(Poly start, Vector3f center, float maxRadius, QueryFilter filter) {
        long startRef = Poly.getCPtr(start);
        SWIGTYPE_p_float centerPos = Converter.convertToSWIGTYPE_p_float(center);
        SWIGTYPE_p_float hitDist = new FloatArray(1).cast();
        SWIGTYPE_p_float hitPos = new FloatArray(3).cast();
        SWIGTYPE_p_float hitNormal = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_findDistanceToWall(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), maxRadius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(hitDist), SWIGTYPE_p_float.getCPtr(hitPos), SWIGTYPE_p_float.getCPtr(hitNormal));
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(hitNormal));
    }

    /**
     * Returns the segments for the specified polygon, optionally including
     * portals.
     *
     * If the segmentRefs parameter is provided, then all polygon segments will
     * be returned. Otherwise only the wall segments are returned.
     *
     * A segment that is normally a portal will be included in the result set as
     * a wall if the filter results in the neighbor polygon becoomming
     * impassable.
     *
     * The segmentVerts and segmentRefs buffers should normally be sized for the
     * maximum segments per polygon of the source navigation mesh.
     *
     * @param poly The reference id of the polygon.
     * @param filter The polygon filter to apply to the query.
     * @param maxSegments The maximum number of segments the result arrays can
     * hold.
     * @return The status flags for the query.
     */
    public Status getPolyWallSegmentsStatus(Poly poly, QueryFilter filter, int maxSegments) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float segmentVerts = new FloatArray(maxSegments * 6).cast();
        SWIGTYPE_p_unsigned_int segmentRefs = new UIntArray(maxSegments).cast();
        SWIGTYPE_p_int segmentCount = new IntArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_getPolyWallSegments(swigCPtr, this, ref, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(segmentVerts), SWIGTYPE_p_unsigned_int.getCPtr(segmentRefs), SWIGTYPE_p_int.getCPtr(segmentCount), maxSegments);
        return new Status(status);
    }

    /**
     * Returns the segments for the specified polygon, optionally including
     * portals.
     *
     * If the segmentRefs parameter is provided, then all polygon segments will
     * be returned. Otherwise only the wall segments are returned.
     *
     * A segment that is normally a portal will be included in the result set as
     * a wall if the filter results in the neighbor polygon becoomming
     * impassable.
     *
     * The segmentVerts and segmentRefs buffers should normally be sized for the
     * maximum segments per polygon of the source navigation mesh.
     *
     * @param poly The reference id of the polygon.
     * @param filter The polygon filter to apply to the query.
     * @param maxSegments The maximum number of segments the result arrays can
     * hold.
     * @return The segments. [(ax, ay, az, bx, by, bz)]
     */
    public Vector3f[] getPolyWallSegments(Poly poly, QueryFilter filter, int maxSegments) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float segmentVerts = new FloatArray(maxSegments * 6).cast();
        SWIGTYPE_p_unsigned_int segmentRefs = new UIntArray(maxSegments).cast();
        SWIGTYPE_p_int segmentCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_getPolyWallSegments(swigCPtr, this, ref, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(segmentVerts), SWIGTYPE_p_unsigned_int.getCPtr(segmentRefs), SWIGTYPE_p_int.getCPtr(segmentCount), maxSegments);
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(segmentVerts), maxSegments * 2);
    }

    /**
     * Returns the segments for the specified polygon, optionally including
     * portals.
     *
     * If the segmentRefs parameter is provided, then all polygon segments will
     * be returned. Otherwise only the wall segments are returned.
     *
     * A segment that is normally a portal will be included in the result set as
     * a wall if the filter results in the neighbor polygon becoomming
     * impassable.
     *
     * The segmentVerts and segmentRefs buffers should normally be sized for the
     * maximum segments per polygon of the source navigation mesh.
     *
     * @param poly The reference id of the polygon.
     * @param filter The polygon filter to apply to the query.
     * @param maxSegments The maximum number of segments the result arrays can
     * hold.
     * @return The reference ids of each segment's neighbor polygon. Or zero if
     * the segment is a wall.
     */
    public Poly[] getPolyWallSegmentsPoly(Poly poly, QueryFilter filter, int maxSegments) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float segmentVerts = new FloatArray(maxSegments * 6).cast();
        SWIGTYPE_p_unsigned_int segmentRefs = new UIntArray(maxSegments).cast();
        SWIGTYPE_p_int segmentCount = new IntArray(1).cast();
        RecastJNI.dtNavMeshQuery_getPolyWallSegments(swigCPtr, this, ref, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_float.getCPtr(segmentVerts), SWIGTYPE_p_unsigned_int.getCPtr(segmentRefs), SWIGTYPE_p_int.getCPtr(segmentCount), maxSegments);
        return Converter.convertToPolys(segmentRefs, segmentCount);
    }

    /*
     * needs to fix random function importer
     public Status findRandomPoint(QueryFilter filter, SWIGTYPE_p_f___float frand, SWIGTYPE_p_unsigned_int randomRef, SWIGTYPE_p_float randomPt) {
     long status = RecastJNI.dtNavMeshQuery_findRandomPoint(swigCPtr, this, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_f___float.getCPtr(frand), SWIGTYPE_p_unsigned_int.getCPtr(randomRef), SWIGTYPE_p_float.getCPtr(randomPt));
     return new Status(status);
     }

     public long findRandomPointAroundCircle(long startRef, SWIGTYPE_p_float centerPos, float maxRadius, QueryFilter filter, SWIGTYPE_p_f___float frand, SWIGTYPE_p_unsigned_int randomRef, SWIGTYPE_p_float randomPt) {
     return RecastJNI.dtNavMeshQuery_findRandomPointAroundCircle(swigCPtr, this, startRef, SWIGTYPE_p_float.getCPtr(centerPos), maxRadius, QueryFilter.getCPtr(filter), filter, SWIGTYPE_p_f___float.getCPtr(frand), SWIGTYPE_p_unsigned_int.getCPtr(randomRef), SWIGTYPE_p_float.getCPtr(randomPt));
     }*/
    /**
     * Finds the closest point on the specified polygon. Uses the detail
     * polygons to find the surface height. (Most accurate.)
     *
     * position does not have to be within the bounds of the polygon or
     * navigation mesh.
     *
     * @param poly The reference id of the polygon.
     * @param position The position to check.
     * @return The status flags for the query.
     */
    public Status closestPointOnPolyStatus(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float closest = new FloatArray(3).cast();
        SWIGTYPE_p_bool posOverPoly = new SWIGTYPE_p_bool();
        long status = RecastJNI.dtNavMeshQuery_closestPointOnPoly(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(closest), SWIGTYPE_p_bool.getCPtr(posOverPoly));
        return new Status(status);
    }

    /**
     * Finds the closest point on the specified polygon. Uses the detail
     * polygons to find the surface height. (Most accurate.)
     *
     * position does not have to be within the bounds of the polygon or
     * navigation mesh.
     *
     * @param poly The reference id of the polygon.
     * @param position The position to check.
     * @return The closest point on the polygon.
     */
    public Vector3f closestPointOnPoly(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float closest = new FloatArray(3).cast();
        SWIGTYPE_p_bool posOverPoly = new SWIGTYPE_p_bool();
        RecastJNI.dtNavMeshQuery_closestPointOnPoly(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(closest), SWIGTYPE_p_bool.getCPtr(posOverPoly));
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(closest));
    }

    /**
     * Returns a point on the boundary closest to the source point if the source
     * point is outside the polygon's xz-bounds.
     *
     * Much faster than closestPointOnPoly().
     *
     * If the provided position lies within the polygon's xz-bounds (above or
     * below), then pos and closest will be equal.
     *
     * The height of closest will be the polygon boundary. The height detail is
     * not used.
     *
     * pos does not have to be within the bounds of the polybon or the
     * navigation mesh.
     *
     * @param poly The reference id to the polygon.
     * @param position The position to check.
     * @return The status flags for the query.
     */
    public Status closestPointOnPolyBoundaryStatus(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float closest = new FloatArray(3).cast();
        long status = RecastJNI.dtNavMeshQuery_closestPointOnPolyBoundary(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(closest));
        return new Status(status);
    }

    /**
     * Returns a point on the boundary closest to the source point if the source
     * point is outside the polygon's xz-bounds.
     *
     * Much faster than closestPointOnPoly().
     *
     * If the provided position lies within the polygon's xz-bounds (above or
     * below), then pos and closest will be equal.
     *
     * The height of closest will be the polygon boundary. The height detail is
     * not used.
     *
     * pos does not have to be within the bounds of the polybon or the
     * navigation mesh.
     *
     * @param poly The reference id to the polygon.
     * @param position The position to check.
     * @return The closest point.
     */
    public Vector3f closestPointOnPolyBoundary(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float closest = new FloatArray(3).cast();
        RecastJNI.dtNavMeshQuery_closestPointOnPolyBoundary(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(closest));
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(closest));
    }

    /**
     * Gets the height of the polygon at the provided position using the height
     * detail. (Most accurate.)
     *
     * @param poly The reference id of the polygon.
     * @param position A position within the xz-bounds of the polygon.
     * @return The status flags for the query. Will return DT_FAILURE if the
     * provided position is outside the xz-bounds of the polygon.
     */
    public Status getPolyHeightStatus(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float height = new FloatArray(1).cast();
        long status = RecastJNI.dtNavMeshQuery_getPolyHeight(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(height));
        return new Status(status);
    }

    /**
     * Gets the height of the polygon at the provided position using the height
     * detail. (Most accurate.)
     *
     * @param poly The reference id of the polygon.
     * @param position A position within the xz-bounds of the polygon.
     * @return The height at the surface of the polygon.
     */
    public float getPolyHeight(Poly poly, Vector3f position) {
        long ref = Poly.getCPtr(poly);
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        SWIGTYPE_p_float height = new FloatArray(1).cast();
        RecastJNI.dtNavMeshQuery_getPolyHeight(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos), SWIGTYPE_p_float.getCPtr(height));
        return Converter.convertToFloat(SWIGTYPE_p_float.getCPtr(height));
    }

    /**
     * Returns true if the polygon reference is valid and passes the filter
     * restrictions.
     *
     * @param poly The polygon reference to check.
     * @param filter The filter to apply.
     * @return
     */
    public boolean isValidPolyRef(Poly poly, QueryFilter filter) {
        long ref = Poly.getCPtr(poly);
        return RecastJNI.dtNavMeshQuery_isValidPolyRef(swigCPtr, this, ref, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Returns true if the polygon reference is in the closed list. The closed
     * list is the list of polygons that were fully evaluated during the last
     * navigation graph search. (A* or Dijkstra)
     *
     * @param poly The reference id of the polygon to check.
     * @return True if the polygon is in closed list.
     */
    public boolean isInClosedList(Poly poly) {
        long ref = Poly.getCPtr(poly);
        return RecastJNI.dtNavMeshQuery_isInClosedList(swigCPtr, this, ref);
    }

    /**
     * Gets the node pool.
     *
     * @return The node pool.
     */
    public NodePool getNodePool() {
        long cPtr = RecastJNI.dtNavMeshQuery_getNodePool(swigCPtr, this);
        return (cPtr == 0) ? null : new NodePool(cPtr, false);
    }

    /**
     * Gets the navigation mesh the query object is using.
     *
     * @return The navigation mesh the query object is using.
     */
    public NavMesh getAttachedNavMesh() {
        long cPtr = RecastJNI.dtNavMeshQuery_getAttachedNavMesh(swigCPtr, this);
        return (cPtr == 0) ? null : new NavMesh(cPtr, false);
    }
} public class Node {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public Node() {
        this(RecastJNI.new_dtNode(), true);
    }

    public Node(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Node obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtNode(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param position Position of the node.
     */
    public void setPosition(Vector3f position) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(position);
        RecastJNI.dtNode_pos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return Position of the node.
     */
    public Vector3f getPosition() {
        long cPtr = RecastJNI.dtNode_pos_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value Cost from previous node to current node.
     */
    public void setCost(float value) {
        RecastJNI.dtNode_cost_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Cost from previous node to current node.
     */
    public float getCost() {
        return RecastJNI.dtNode_cost_get(swigCPtr, this);
    }

    /**
     *
     * @param value Cost up to the node.
     */
    public void setTotal(float value) {
        RecastJNI.dtNode_total_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Cost up to the node.
     */
    public float getTotal() {
        return RecastJNI.dtNode_total_get(swigCPtr, this);
    }

    /**
     *
     * @param value Index to parent node.
     */
    public void setParentIndex(long value) {
        RecastJNI.dtNode_pidx_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Index to parent node.
     */
    public long getParenIndex() {
        return RecastJNI.dtNode_pidx_get(swigCPtr, this);
    }

    /**
     *
     * @param value Node flags 0/open/closed.
     */
    public void setFlags(long value) {
        RecastJNI.dtNode_flags_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Node flags 0/open/closed.
     */
    public long getFlags() {
        return RecastJNI.dtNode_flags_get(swigCPtr, this);
    }

    /**
     *
     * @param value Polygon ref the node corresponds to.
     */
    public void setId(Poly poly) {
        long value = Poly.getCPtr(poly);
        RecastJNI.dtNode_id_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Polygon ref the node corresponds to.
     */
    public Poly getId() {
        long pointer = RecastJNI.dtNode_id_get(swigCPtr, this);
        return (pointer == 0) ? null : new Poly(pointer, false);
    }
} public class NodePool {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NodePool(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NodePool obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtNodePool(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public NodePool(int maxNodes, int hashSize) {
        this(RecastJNI.new_dtNodePool(maxNodes, hashSize), true);
    }

    public void clear() {
        RecastJNI.dtNodePool_clear(swigCPtr, this);
    }

    public Node getNode(long id) {
        long cPtr = RecastJNI.dtNodePool_getNode(swigCPtr, this, id);
        return (cPtr == 0) ? null : new Node(cPtr, false);
    }

    public Node findNode(long id) {
        long cPtr = RecastJNI.dtNodePool_findNode(swigCPtr, this, id);
        return (cPtr == 0) ? null : new Node(cPtr, false);
    }

    public long getNodeIdx(Node node) {
        return RecastJNI.dtNodePool_getNodeIdx(swigCPtr, this, Node.getCPtr(node), node);
    }

    public Node getNodeAtIdx(long idx) {
        long cPtr = RecastJNI.dtNodePool_getNodeAtIdx__SWIG_0(swigCPtr, this, idx);
        return (cPtr == 0) ? null : new Node(cPtr, false);
    }

    public int getMemUsed() {
        return RecastJNI.dtNodePool_getMemUsed(swigCPtr, this);
    }

    public int getMaxNodes() {
        return RecastJNI.dtNodePool_getMaxNodes(swigCPtr, this);
    }

    public int getHashSize() {
        return RecastJNI.dtNodePool_getHashSize(swigCPtr, this);
    }

    public int getFirst(int bucket) {
        return RecastJNI.dtNodePool_getFirst(swigCPtr, this, bucket);
    }

    public int getNext(int i) {
        return RecastJNI.dtNodePool_getNext(swigCPtr, this, i);
    }
} public class NodeQueue {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public NodeQueue(int n) {
        this(RecastJNI.new_dtNodeQueue(n), true);
    }

    public NodeQueue(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(NodeQueue obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtNodeQueue(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void clear() {
        RecastJNI.dtNodeQueue_clear(swigCPtr, this);
    }

    public Node top() {
        long cPtr = RecastJNI.dtNodeQueue_top(swigCPtr, this);
        return (cPtr == 0) ? null : new Node(cPtr, false);
    }

    public Node pop() {
        long cPtr = RecastJNI.dtNodeQueue_pop(swigCPtr, this);
        return (cPtr == 0) ? null : new Node(cPtr, false);
    }

    public void push(Node node) {
        RecastJNI.dtNodeQueue_push(swigCPtr, this, Node.getCPtr(node), node);
    }

    public void modify(Node node) {
        RecastJNI.dtNodeQueue_modify(swigCPtr, this, Node.getCPtr(node), node);
    }

    public boolean empty() {
        return RecastJNI.dtNodeQueue_empty(swigCPtr, this);
    }

    public int getMemoryUsed() {
        return RecastJNI.dtNodeQueue_getMemUsed(swigCPtr, this);
    }

    public int getCapacity() {
        return RecastJNI.dtNodeQueue_getCapacity(swigCPtr, this);
    }
} public class OffMeshConnection {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public OffMeshConnection() {
        this(RecastJNI.new_dtOffMeshConnection(), true);
    }

    public OffMeshConnection(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(OffMeshConnection obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtOffMeshConnection(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * For a properly built navigation mesh, vertex A will always be within the
     * bounds of the mesh. Vertex B is not required to be within the bounds of
     * the mesh.
     *
     * @param position The endpoints of the connection. [(ax, ay, az, bx, by,
     * bz)].
     */
    public void setPosition(Vector3f[] position) {
        if (position.length != 2) {
            throw new RuntimeException("length of position must be 2");
        }
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(position);
        RecastJNI.dtOffMeshConnection_pos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     * For a properly built navigation mesh, vertex A will always be within the
     * bounds of the mesh. Vertex B is not required to be within the bounds of
     * the mesh.
     *
     * @return The endpoints of the connection. [(ax, ay, az, bx, by, bz)].
     */
    public Vector3f[] getPosition() {
        long cPtr = RecastJNI.dtOffMeshConnection_pos_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr, 2);
    }

    /**
     *
     * @param value The radius of the endpoints. [Limit: >= 0].
     */
    public void setRadius(float value) {
        RecastJNI.dtOffMeshConnection_rad_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The radius of the endpoints. [Limit: >= 0].
     */
    public float getRadius() {
        return RecastJNI.dtOffMeshConnection_rad_get(swigCPtr, this);
    }

    /**
     *
     * @param value The polygon reference of the connection within the tile.
     */
    public void setPolygon(int value) {
        RecastJNI.dtOffMeshConnection_poly_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The polygon reference of the connection within the tile.
     */
    public int getPolygon() {
        return RecastJNI.dtOffMeshConnection_poly_get(swigCPtr, this);
    }

    /**
     * These are not the connection's user defined flags. Those are assigned via
     * the connection's Poly definition. These are link flags used for internal
     * purposes.
     *
     * @see Poly
     * @param value Link flags.
     */
    public void setFlags(short value) {
        RecastJNI.dtOffMeshConnection_flags_set(swigCPtr, this, value);
    }

    /**
     * These are not the connection's user defined flags. Those are assigned via
     * the connection's Poly definition. These are link flags used for internal
     * purposes.
     *
     * @see Poly
     * @return Link flags.
     */
    public short getFlags() {
        return RecastJNI.dtOffMeshConnection_flags_get(swigCPtr, this);
    }

    /**
     *
     * @param value End point side.
     */
    public void setSide(short value) {
        RecastJNI.dtOffMeshConnection_side_set(swigCPtr, this, value);
    }

    /**
     *
     * @return End point side.
     */
    public short getSide() {
        return RecastJNI.dtOffMeshConnection_side_get(swigCPtr, this);
    }

    /**
     *
     * @param value The id of the offmesh connection. (User assigned when the
     * navigation mesh is built.)
     */
    public void setUserId(long value) {
        RecastJNI.dtOffMeshConnection_userId_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The id of the offmesh connection. (User assigned when the
     * navigation mesh is built.)
     */
    public long getUserId() {
        return RecastJNI.dtOffMeshConnection_userId_get(swigCPtr, this);
    }
} public class PathCorridor {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public PathCorridor() {
        this(RecastJNI.new_dtPathCorridor(), true);
    }

    public PathCorridor(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(PathCorridor obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtPathCorridor(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * Allocates the corridor's path buffer.
     *
     * WARNING: Cannot be called more than once.
     *
     * @param maxPath The maximum path size the corridor can handle.
     * @return True if the initialization succeeded.
     */
    public boolean init(int maxPath) {
        return RecastJNI.dtPathCorridor_init(swigCPtr, this, maxPath);
    }

    /**
     * Resets the path corridor to the specified position.
     *
     * Essentially, the corridor is set of one polygon in size with the target
     * equal to the position.
     *
     * @param ref The polygon reference containing the position.
     * @param position The new position in the corridor.
     */
    public void reset(long ref, Vector3f position) {
        SWIGTYPE_p_float pos = Converter.convertToSWIGTYPE_p_float(position);
        RecastJNI.dtPathCorridor_reset(swigCPtr, this, ref, SWIGTYPE_p_float.getCPtr(pos));
    }

    /**
     * Finds the corners in the corridor from the position toward the target.
     *
     * @param maxCorners The maximum number of corners the buffers can hold.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return The corner vertices. [(x, y, z) * cornerCount] [Size: less or
     * equal to maxCorners]
     */
    public Vector3f[] findCornersVerts(int maxCorners, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float cornerVerts = new FloatArray(3 * maxCorners).cast();
        SWIGTYPE_p_unsigned_char cornerFlags = new UCharArray(maxCorners).cast();
        SWIGTYPE_p_unsigned_int cornerPolys = new UIntArray(maxCorners).cast();
        int count = RecastJNI.dtPathCorridor_findCorners(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cornerVerts), SWIGTYPE_p_unsigned_char.getCPtr(cornerFlags), SWIGTYPE_p_unsigned_int.getCPtr(cornerPolys), maxCorners, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
        return Converter.convertToVector3f(SWIGTYPE_p_float.getCPtr(cornerVerts), count);
    }

    /**
     * Finds the corners in the corridor from the position toward the target.
     *
     * @param maxCorners The maximum number of corners the buffers can hold.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return The flag for each corner. [(flag) * cornerCount] [Size: less or
     * equal to maxCorners]
     */
    public char[] findCornersFlags(int maxCorners, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float cornerVerts = new FloatArray(3 * maxCorners).cast();
        SWIGTYPE_p_unsigned_char cornerFlags = new UCharArray(maxCorners).cast();
        SWIGTYPE_p_unsigned_int cornerPolys = new UIntArray(maxCorners).cast();
        int count = RecastJNI.dtPathCorridor_findCorners(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cornerVerts), SWIGTYPE_p_unsigned_char.getCPtr(cornerFlags), SWIGTYPE_p_unsigned_int.getCPtr(cornerPolys), maxCorners, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
        return Converter.convertToChars(cornerFlags, count);
    }

    /**
     * Finds the corners in the corridor from the position toward the target.
     *
     * @param maxCorners The maximum number of corners the buffers can hold.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return The polygon reference for each corner. [(polyRef) * cornerCount]
     * [Size: less or equal to maxCorners]
     */
    public int[] findCorners(int maxCorners, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float cornerVerts = new FloatArray(3 * maxCorners).cast();
        SWIGTYPE_p_unsigned_char cornerFlags = new UCharArray(maxCorners).cast();
        SWIGTYPE_p_unsigned_int cornerPolys = new UIntArray(maxCorners).cast();
        int count = RecastJNI.dtPathCorridor_findCorners(swigCPtr, this, SWIGTYPE_p_float.getCPtr(cornerVerts), SWIGTYPE_p_unsigned_char.getCPtr(cornerFlags), SWIGTYPE_p_unsigned_int.getCPtr(cornerPolys), maxCorners, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
        return Converter.convertToInts(SWIGTYPE_p_unsigned_int.getCPtr(cornerPolys), count);
    }

    /**
     * Attempts to optimize the path if the specified point is visible from the
     * current position.
     *
     * @param nextPoint The point to search toward.
     * @param pathOptimizationRange The maximum range to search. [Limit: > 0]
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     */
    public void optimizePathVisibility(Vector3f nextPoint, float pathOptimizationRange, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float next = Converter.convertToSWIGTYPE_p_float(nextPoint);
        RecastJNI.dtPathCorridor_optimizePathVisibility(swigCPtr, this, SWIGTYPE_p_float.getCPtr(next), pathOptimizationRange, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Attempts to optimize the path using a local area search. (Partial
     * replanning.) Inaccurate locomotion or dynamic obstacle avoidance can
     * force the agent position significantly outside the original corridor.
     * Over time this can result in the formation of a non-optimal corridor.
     * This function will use a local area path search to try to re-optimize the
     * corridor.
     *
     * The more inaccurate the agent movement, the more beneficial this function
     * becomes. Simply adjust the frequency of the call to match the needs to
     * the agent.
     *
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return
     */
    public boolean optimizePathTopology(NavMeshQuery navQuery, QueryFilter filter) {
        return RecastJNI.dtPathCorridor_optimizePathTopology(swigCPtr, this, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * There is no documentation so I don't know how it is supposed to be
     * used... so it is not finished yet...
     *
     * @param offMeshConRef
     * @param refs
     * @param startPosition
     * @param endPosition
     * @param navquery
     * @return
     */
    public boolean moveOverOffmeshConnection(long offMeshConRef, SWIGTYPE_p_unsigned_int refs, Vector3f startPosition, Vector3f endPosition, NavMeshQuery navquery) {
        SWIGTYPE_p_float startPos = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float endPos = Converter.convertToSWIGTYPE_p_float(endPosition);
        return RecastJNI.dtPathCorridor_moveOverOffmeshConnection(swigCPtr, this, offMeshConRef, SWIGTYPE_p_unsigned_int.getCPtr(refs), SWIGTYPE_p_float.getCPtr(startPos), SWIGTYPE_p_float.getCPtr(endPos), NavMeshQuery.getCPtr(navquery), navquery);
    }

    public boolean fixPathStart(long safeRef, Vector3f safePosition) {
        SWIGTYPE_p_float safePos = Converter.convertToSWIGTYPE_p_float(safePosition);
        return RecastJNI.dtPathCorridor_fixPathStart(swigCPtr, this, safeRef, SWIGTYPE_p_float.getCPtr(safePos));
    }

    /**
     * There is no documentation so I don't know how it is supposed to be
     * used... so it is not finished yet...
     *
     * @param safeRef
     * @param safePos
     * @param navquery
     * @param filter
     * @return
     */
    public boolean trimInvalidPath(long safeRef, SWIGTYPE_p_float safePos, NavMeshQuery navquery, QueryFilter filter) {
        return RecastJNI.dtPathCorridor_trimInvalidPath(swigCPtr, this, safeRef, SWIGTYPE_p_float.getCPtr(safePos), NavMeshQuery.getCPtr(navquery), navquery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Checks the current corridor path to see if its polygon references remain
     * valid.
     *
     * The path can be invalidated if there are structural changes to the
     * underlying navigation mesh, or the state of a polygon within the path
     * changes resulting in it being filtered out. (E.g. An exclusion or
     * inclusion flag changes.)
     *
     * @param maxLookAhead The number of polygons from the beginning of the
     * corridor to search.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return
     */
    public boolean isValid(int maxLookAhead, NavMeshQuery navQuery, QueryFilter filter) {
        return RecastJNI.dtPathCorridor_isValid(swigCPtr, this, maxLookAhead, NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Moves the position from the current location to the desired location,
     * adjusting the corridor as needed to reflect the change.
     *
     * Behavior:
     *
     * The movement is constrained to the surface of the navigation mesh. The
     * corridor is automatically adjusted (shorted or lengthened) in order to
     * remain valid. The new position will be located in the adjusted corridor's
     * first polygon. The expected use case is that the desired position will be
     * 'near' the current corridor. What is considered 'near' depends on local
     * polygon density, query search extents, etc.
     *
     * The resulting position will differ from the desired position if the
     * desired position is not on the navigation mesh, or it can't be reached
     * using a local search.
     *
     * @param desiredPosition The desired new position.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return Returns true if move succeeded.
     */
    public boolean movePosition(Vector3f desiredPosition, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float npos = Converter.convertToSWIGTYPE_p_float(desiredPosition);
        return RecastJNI.dtPathCorridor_movePosition(swigCPtr, this, SWIGTYPE_p_float.getCPtr(npos), NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Moves the target from the curent location to the desired location,
     * adjusting the corridor as needed to reflect the change.
     *
     * Behavior:
     *
     * The movement is constrained to the surface of the navigation mesh. The
     * corridor is automatically adjusted (shorted or lengthened) in order to
     * remain valid. The new target will be located in the adjusted corridor's
     * last polygon. The expected use case is that the desired target will be
     * 'near' the current corridor. What is considered 'near' depends on local
     * polygon density, query search extents, etc.
     *
     * The resulting target will differ from the desired target if the desired
     * target is not on the navigation mesh, or it can't be reached using a
     * local search.
     *
     * @param desiredPosition The desired new target position.
     * @param navQuery The query object used to build the corridor.
     * @param filter The filter to apply to the operation.
     * @return Returns true if move succeeded.
     */
    public boolean moveTargetPosition(Vector3f desiredPosition, NavMeshQuery navQuery, QueryFilter filter) {
        SWIGTYPE_p_float npos = Converter.convertToSWIGTYPE_p_float(desiredPosition);
        return RecastJNI.dtPathCorridor_moveTargetPosition(swigCPtr, this, SWIGTYPE_p_float.getCPtr(npos), NavMeshQuery.getCPtr(navQuery), navQuery, QueryFilter.getCPtr(filter), filter);
    }

    /**
     * Loads a new path and target into the corridor. The current corridor
     * position is expected to be within the first polygon in the path. The
     * target is expected to be in the last polygon.
     *
     * Warning: The size of the path must not exceed the size of corridor's path
     * buffer set during init().
     *
     * @param targetPosition The target location within the last polygon of the
     * path.
     * @param polyRefs The path corridor.
     * @param numberOfPolysInPath The number of polygons in the path.
     */
    public void setCorridor(Vector3f targetPosition, int[] polyRefs, int numberOfPolysInPath) {
        SWIGTYPE_p_float target = Converter.convertToSWIGTYPE_p_float(targetPosition);
        SWIGTYPE_p_unsigned_int polys = Converter.convertToSWIGTYPE_p_unsigned_int(polyRefs);
        RecastJNI.dtPathCorridor_setCorridor(swigCPtr, this, SWIGTYPE_p_float.getCPtr(target), SWIGTYPE_p_unsigned_int.getCPtr(polys), numberOfPolysInPath);
    }

    /**
     * Gets the current position within the corridor. (In the first polygon.)
     *
     * @return The current position within the corridor.
     */
    public Vector3f getPosition() {
        long cPtr = RecastJNI.dtPathCorridor_getPos(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     * Gets the current target within the corridor. (In the last polygon.)
     *
     * @return The current target within the corridor.
     */
    public Vector3f getTarget() {
        long cPtr = RecastJNI.dtPathCorridor_getTarget(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    /**
     * The polygon reference id of the first polygon in the corridor, the
     * polygon containing the position.
     *
     * @return The polygon reference id of the first polygon in the corridor.
     * (Or zero if there is no path.)
     */
    public long getFirstPoly() {
        return RecastJNI.dtPathCorridor_getFirstPoly(swigCPtr, this);
    }

    /**
     * The polygon reference id of the last polygon in the corridor, the polygon
     * containing the target.
     *
     * @return The polygon reference id of the last polygon in the corridor. (Or
     * zero if there is no path.)
     */
    public long getLastPoly() {
        return RecastJNI.dtPathCorridor_getLastPoly(swigCPtr, this);
    }

    /**
     * The corridor's path.
     *
     * @return The corridor's path. [(polyRef) * getPathCount()]
     * @see PathCorridor#getPathCount()
     */
    public int[] getPath() {
        long cPtr = RecastJNI.dtPathCorridor_getPath(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToInts(cPtr, getPathCount());
    }

    /**
     * The number of polygons in the current corridor path.
     *
     * @return The number of polygons in the current corridor path.
     */
    public int getPathCount() {
        return RecastJNI.dtPathCorridor_getPathCount(swigCPtr, this);
    }
} public class Poly {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public Poly() {
        this(RecastJNI.new_dtPoly(), true);
    }

    public Poly(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Poly obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtPoly(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value Index to first link in linked list. (Or DT_NULL_LINK if
     * there is no link.)
     */
    public void setFirstLink(long value) {
        RecastJNI.dtPoly_firstLink_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Index to first link in linked list. (Or DT_NULL_LINK if there is
     * no link.)
     */
    public long getFirstLink() {
        return RecastJNI.dtPoly_firstLink_get(swigCPtr, this);
    }

    /**
     *
     * @param vertices The indices of the polygon's vertices.
     * @see MeshTile#getVertices()
     */
    public void setVertices(short[] vertices) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(vertices);
        RecastJNI.dtPoly_verts_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The indices of the polygon's vertices.
     * @see MeshTile#getVertices()
     */
    public short[] getVertices() {
        long cPtr = RecastJNI.dtPoly_verts_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getVerticesCount());
    }

    /**
     * Note: probably doesn't work as expected
     *
     * @param neighbours Packed data representing neighbor polygons references
     * and flags for each edge.
     *
     * Each entry represents data for the edge starting at the vertex of the
     * same index. E.g. The entry at index n represents the edge data for
     * vertex[n] to vertex[n+1].
     *
     * A value of zero indicates the edge has no polygon connection. (It makes
     * up the border of the navigation mesh.)
     */
    public void setNeighbours(short[] neighbours) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(neighbours);
        RecastJNI.dtPoly_neis_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     * Note: probably doesn't work as expected
     *
     * @return Packed data representing neighbor polygons references and flags
     * for each edge.
     *
     * Each entry represents data for the edge starting at the vertex of the
     * same index. E.g. The entry at index n represents the edge data for
     * vertex[n] to vertex[n+1].
     *
     * A value of zero indicates the edge has no polygon connection. (It makes
     * up the border of the navigation mesh.)
     */
    public short[] getNeighbours() {
        long cPtr = RecastJNI.dtPoly_neis_get(swigCPtr, this);
        //check count
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getVerticesCount());
    }

    /**
     *
     * @param value The user defined polygon flags.
     */
    public void setFlags(int value) {
        RecastJNI.dtPoly_flags_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The user defined polygon flags.
     */
    public int getFlags() {
        return RecastJNI.dtPoly_flags_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of vertices in the polygon.
     */
    public void setVerticesCount(short value) {
        RecastJNI.dtPoly_vertCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices in the polygon.
     */
    public short getVerticesCount() {
        return RecastJNI.dtPoly_vertCount_get(swigCPtr, this);
    }

    /**
     * Sets the user defined area id. [Limit: less than DT_MAX_AREAS].
     *
     * @param a
     */
    public void setArea(short a) {
        RecastJNI.dtPoly_setArea(swigCPtr, this, a);
    }

    /**
     * Sets the polygon type
     *
     * @param t
     * @see PolyTypes
     */
    public void setType(short t) {
        RecastJNI.dtPoly_setType(swigCPtr, this, t);
    }

    /**
     * Gets the user defined area id.
     *
     * @return
     */
    public short getArea() {
        return RecastJNI.dtPoly_getArea(swigCPtr, this);
    }

    /**
     * Gets the polygon type.
     *
     * @return
     * @see PolyTypes
     */
    public short getType() {
        return RecastJNI.dtPoly_getType(swigCPtr, this);
    }

    public void setSwigCPtr(long swigCPtr) {
        if (this.swigCPtr==swigCPtr) {
            return;
        }
        delete();
        this.swigCPtr = swigCPtr;
    }
    
    
} public class PolyDetail {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public PolyDetail() {
        this(RecastJNI.new_dtPolyDetail(), true);
    }

    public PolyDetail(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(PolyDetail obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtPolyDetail(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The offset of the vertices in the MeshTile.detailVertices
     * array.
     * @see MeshTile#getDetailVertices()
     */
    public void setVertBase(long value) {
        RecastJNI.dtPolyDetail_vertBase_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The offset of the vertices in the MeshTile.detailVertices array.
     * @see MeshTile#getDetailVertices()
     */
    public long getVertBase() {
        return RecastJNI.dtPolyDetail_vertBase_get(swigCPtr, this);
    }

    /**
     *
     * @param value he offset of the triangles in the MeshTile.detailTriangles
     * array.
     * @see MeshTile#getDetailTriangles()
     */
    public void setTriangleBase(long value) {
        RecastJNI.dtPolyDetail_triBase_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The offset of the triangles in the MeshTile.detailTriangles
     * array.
     * @see MeshTile#getDetailTriangles()
     */
    public long getTriangleBase() {
        return RecastJNI.dtPolyDetail_triBase_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of vertices in the sub-mesh.
     */
    public void setVerticesCount(short value) {
        RecastJNI.dtPolyDetail_vertCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices in the sub-mesh.
     */
    public short getVerticesCount() {
        return RecastJNI.dtPolyDetail_vertCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of triangles in the sub-mesh.
     */
    public void setTriangleCount(short value) {
        RecastJNI.dtPolyDetail_triCount_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of triangles in the sub-mesh.
     */
    public short getTriangleCount() {
        return RecastJNI.dtPolyDetail_triCount_get(swigCPtr, this);
    }
} public class QueryFilter {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public QueryFilter() {
        this(RecastJNI.new_dtQueryFilter(), true);
    }

    public QueryFilter(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(QueryFilter obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtQueryFilter(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * Returns true if the polygon can be visited. (I.e. Is traversable.)
     *
     * @param ref The reference id of the polygon test.
     * @param tile The tile containing the polygon.
     * @param poly The polygon to test.
     * @return
     */
    public boolean passFilter(long ref, MeshTile tile, Poly poly) {
        return RecastJNI.dtQueryFilter_passFilter(swigCPtr, this, ref, MeshTile.getCPtr(tile), tile, Poly.getCPtr(poly), poly);
    }

    /**
     *
     * @param startPosition The start position on the edge of the previous and
     * current polygon.
     * @param endPosition The end position on the edge of the current and next
     * polygon.
     * @param prevRef The reference id of the previous polygon. [opt]
     * @param prevTile The tile containing the previous polygon. [opt]
     * @param prevPoly The previous polygon. [opt]
     * @param curRef The reference id of the current polygon.
     * @param curTile The tile containing the current polygon.
     * @param curPoly The current polygon.
     * @param nextRef The refernece id of the next polygon. [opt]
     * @param nextTile The tile containing the next polygon. [opt]
     * @param nextPoly The next polygon. [opt]
     * @return
     */
    public float getCost(Vector3f startPosition, Vector3f endPosition, long prevRef, MeshTile prevTile, Poly prevPoly, long curRef, MeshTile curTile, Poly curPoly, long nextRef, MeshTile nextTile, Poly nextPoly) {
        SWIGTYPE_p_float pa = Converter.convertToSWIGTYPE_p_float(startPosition);
        SWIGTYPE_p_float pb = Converter.convertToSWIGTYPE_p_float(endPosition);
        return RecastJNI.dtQueryFilter_getCost(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pa), SWIGTYPE_p_float.getCPtr(pb), prevRef, MeshTile.getCPtr(prevTile), prevTile, Poly.getCPtr(prevPoly), prevPoly, curRef, MeshTile.getCPtr(curTile), curTile, Poly.getCPtr(curPoly), curPoly, nextRef, MeshTile.getCPtr(nextTile), nextTile, Poly.getCPtr(nextPoly), nextPoly);
    }

    /**
     * Returns the traversal cost of the area.
     *
     * @param i The id of the area.
     * @return The traversal cost of the area.
     */
    public float getAreaCost(int i) {
        return RecastJNI.dtQueryFilter_getAreaCost(swigCPtr, this, i);
    }

    /**
     * Sets the traversal cost of the area.
     *
     * @param i The id of the area.
     * @param cost The new cost of traversing the area.
     */
    public void setAreaCost(int i, float cost) {
        RecastJNI.dtQueryFilter_setAreaCost(swigCPtr, this, i, cost);
    }

    /**
     * Any polygons that include one or more of these flags will be included in
     * the operation.
     *
     * @return Returns the include flags for the filter.
     */
    public int getIncludeFlags() {
        return RecastJNI.dtQueryFilter_getIncludeFlags(swigCPtr, this);
    }

    /**
     * Sets the include flags for the filter.
     *
     * @param flags The new flags.
     */
    public void setIncludeFlags(int flags) {
        RecastJNI.dtQueryFilter_setIncludeFlags(swigCPtr, this, flags);
    }

    /**
     * Any polygons that include one ore more of these flags will be excluded
     * from the operation.
     *
     * @return Returns the exclude flags for the filter.
     */
    public int getExcludeFlags() {
        return RecastJNI.dtQueryFilter_getExcludeFlags(swigCPtr, this);
    }

    /**
     * Sets the exclude flags for the filter.
     *
     * @param flags The new flags.
     */
    public void setExcludeFlags(int flags) {
        RecastJNI.dtQueryFilter_setExcludeFlags(swigCPtr, this, flags);
    }
} public class CompactCell {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Internal use only.
     */
    protected CompactCell(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(CompactCell obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcCompactCell(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

//    public void setIndex(long value) {
//        RecastJNI.rcCompactCell_index_set(swigCPtr, this, value);
//    }
    /**
     *
     * @return Index to the first span in the column.
     */
    public long getIndex() {
        return RecastJNI.rcCompactCell_index_get(swigCPtr, this);
    }

//    public void setCount(long value) {
//        RecastJNI.rcCompactCell_count_set(swigCPtr, this, value);
//    }
    /**
     *
     * @return Number of spans in the column.
     */
    public long getCount() {
        return RecastJNI.rcCompactCell_count_get(swigCPtr, this);
    }
} public class CompactHeightfield {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a compact heightfield object using the Recast allocator.
     */
    public CompactHeightfield() {
        swigCPtr = RecastJNI.rcAllocCompactHeightfield();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected CompactHeightfield(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(CompactHeightfield obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreeCompactHeightfield(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The width of the heightfield. (Along the x-axis in cell
     * units.)
     */
    public void setWidth(int value) {
        RecastJNI.rcCompactHeightfield_width_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of the heightfield. (Along the x-axis in cell units.)
     */
    public int getWidth() {
        return RecastJNI.rcCompactHeightfield_width_get(swigCPtr, this);
    }

    /**
     *
     * @param height The height of the heightfield. (Along the z-axis in cell
     * units.)
     */
    public void setHeight(int height) {
        RecastJNI.rcCompactHeightfield_height_set(swigCPtr, this, height);
    }

    /**
     *
     * @return The height of the heightfield. (Along the z-axis in cell units.)
     */
    public int getHeight() {
        return RecastJNI.rcCompactHeightfield_height_get(swigCPtr, this);
    }

//    /**
//     *
//     * @param spanCount The number of spans in the heightfield.
//     */
//    protected void setSpanCount(int spanCount) {
//        RecastJNI.rcCompactHeightfield_spanCount_set(swigCPtr, this, spanCount);
//    }
    /**
     *
     * @return The number of spans in the heightfield.
     */
    protected int getSpanCount() {
        return RecastJNI.rcCompactHeightfield_spanCount_get(swigCPtr, this);
    }

    /**
     *
     * @param value The walkable height used during the build of the field.
     * @see Config#walkableHeight
     */
    public void setWalkableHeight(int value) {
        RecastJNI.rcCompactHeightfield_walkableHeight_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The walkable height used during the build of the field.
     * @see Config#walkableHeight
     */
    public int getWalkableHeight() {
        return RecastJNI.rcCompactHeightfield_walkableHeight_get(swigCPtr, this);
    }

    /**
     *
     * @param value The walkable climb used during the build of the field.
     * @see Config#walkableClimb
     */
    public void setWalkableClimb(int value) {
        RecastJNI.rcCompactHeightfield_walkableClimb_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The walkable climb used during the build of the field.
     * @see Config#walkableClimb
     */
    public int getWalkableClimb() {
        return RecastJNI.rcCompactHeightfield_walkableClimb_get(swigCPtr, this);
    }

    /**
     *
     * @param value The AABB border size used during the build of the field.
     * @see Config#borderSize
     */
    public void setBorderSize(int value) {
        RecastJNI.rcCompactHeightfield_borderSize_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The AABB border size used during the build of the field.
     * @see Config#borderSize
     */
    public int getBorderSize() {
        return RecastJNI.rcCompactHeightfield_borderSize_get(swigCPtr, this);
    }

    /**
     *
     * @param maxDistance The maximum distance value of any span within the
     * field.
     */
    public void setMaxDistance(int maxDistance) {
        RecastJNI.rcCompactHeightfield_maxDistance_set(swigCPtr, this, maxDistance);
    }

    /**
     *
     * @return The maximum distance value of any span within the field.
     */
    public int getMaxDistance() {
        return RecastJNI.rcCompactHeightfield_maxDistance_get(swigCPtr, this);
    }

    /**
     *
     * @param maxRegions The maximum region id of any span within the field.
     */
    public void setMaxRegions(int maxRegions) {
        RecastJNI.rcCompactHeightfield_maxRegions_set(swigCPtr, this, maxRegions);
    }

    /**
     *
     * @return The maximum region id of any span within the field.
     */
    public int getMaxRegions() {
        return RecastJNI.rcCompactHeightfield_maxRegions_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds in world space.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcCompactHeightfield_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds in world space.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcCompactHeightfield_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds in world space.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcCompactHeightfield_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds in world space.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcCompactHeightfield_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The size of each cell. (On the xz-plane.)
     */
    public void setCellSize(float value) {
        RecastJNI.rcCompactHeightfield_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The size of each cell. (On the xz-plane.)
     */
    public float getCellSize() {
        return RecastJNI.rcCompactHeightfield_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public void setCellHeight(float value) {
        RecastJNI.rcCompactHeightfield_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public float getCellHeight() {
        return RecastJNI.rcCompactHeightfield_ch_get(swigCPtr, this);
    }

//    /**
//     * -not done yet
//     *
//     * @param value Array of cells.
//     */
//    public void setCells(CompactCell value) {
//        RecastJNI.rcCompactHeightfield_cells_set(swigCPtr, this, CompactCell.getCPtr(value), value);
//    }
    /**
     *
     * @return Array of cells.
     */
    public CompactCell[] getCells() {
        long cPtr = RecastJNI.rcCompactHeightfield_cells_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        int length = getHeight() * getWidth();
        CompactCell[] compactCells = new CompactCell[length];
        for (int i = 0; i < length; i++) {
            compactCells[i] = new CompactCell(cPtr + i, false);
        }
        return compactCells;
    }

//    /**
//     * -not done yet
//     *
//     * @param value Array of spans.
//     */
//    public void setSpans(CompactSpan value) {
//        RecastJNI.rcCompactHeightfield_spans_set(swigCPtr, this, CompactSpan.getCPtr(value), value);
//    }
    /**
     *
     * @return Array of spans.
     */
    public CompactSpan[] getSpans() {
        long cPtr = RecastJNI.rcCompactHeightfield_spans_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        CompactSpan[] compactSpans = new CompactSpan[getSpanCount()];
        for (int i = 0; i < compactSpans.length; i++) {
            compactSpans[i] = new CompactSpan(cPtr + i, false);

        }
        return compactSpans;
    }

    /**
     *
     * @param distance Array containing border distance data.
     */
    public void setDistances(short[] distance) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(distance);
        RecastJNI.rcCompactHeightfield_dist_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Array containing border distance data.
     */
    public short[] getDistances() {
        long cPtr = RecastJNI.rcCompactHeightfield_dist_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToShorts(cPtr, getSpanCount());
    }

    /**
     *
     * @param areas Array containing area id data.
     */
    public void setAreas(char[] areas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(areas);
        RecastJNI.rcCompactHeightfield_areas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return Array containing area id data.
     */
    public char[] getAreas() {
        long cPtr = RecastJNI.rcCompactHeightfield_areas_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getSpanCount());
    }
} public class CompactSpan {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Internal use only.
     */
    protected CompactSpan(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(CompactSpan obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcCompactSpan(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The lower extent of the span. (Measured from the
     * heightfield's base.)
     */
    public void setY(int value) {
        RecastJNI.rcCompactSpan_y_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The lower extent of the span. (Measured from the heightfield's
     * base.)
     */
    public int getY() {
        return RecastJNI.rcCompactSpan_y_get(swigCPtr, this);
    }

    /**
     *
     * @param value The id of the region the span belongs to. (Or zero if not in
     * a region.)
     */
    public void setRegionID(int value) {
        RecastJNI.rcCompactSpan_reg_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The id of the region the span belongs to. (Or zero if not in a
     * region.)
     */
    public int getRegionID() {
        return RecastJNI.rcCompactSpan_reg_get(swigCPtr, this);
    }

    /**
     *
     * @param value Packed neighbor connection data.
     */
    public void setConnnection(long value) {
        RecastJNI.rcCompactSpan_con_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Packed neighbor connection data.
     */
    public long getConnection() {
        return RecastJNI.rcCompactSpan_con_get(swigCPtr, this);
    }

    /**
     * @param value The height of the span. (Measured from y.)
     */
    public void setHeight(long value) {
        RecastJNI.rcCompactSpan_h_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the span. (Measured from y.)
     */
    public long getHeight() {
        return RecastJNI.rcCompactSpan_h_get(swigCPtr, this);
    }
} public class Config {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public Config() {
        this(RecastJNI.new_rcConfig(), true);
    }

    protected Config(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Config obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcConfig(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The width of the field along the x-axis. [Limit: >= 0]
     * [Units: vx].
     */
    public void setWidth(int value) {
        RecastJNI.rcConfig_width_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of the field along the x-axis. [Limit: >= 0] [Units:
     * vx].
     */
    public int getWidth() {
        return RecastJNI.rcConfig_width_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of the field along the z-axis. [Limit: >= 0]
     * [Units: vx].
     */
    public void setHeight(int value) {
        RecastJNI.rcConfig_height_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the field along the z-axis. [Limit: >= 0] [Units:
     * vx].
     */
    public int getHeight() {
        return RecastJNI.rcConfig_height_get(swigCPtr, this);
    }

    /**
     * This field is only used when building multi-tile meshes.
     *
     * @param value The width/height size of tile's on the xz-plane. [Limit: >=
     * 0] [Units: vx].
     */
    public void setTileSize(int value) {
        RecastJNI.rcConfig_tileSize_set(swigCPtr, this, value);
    }

    /**
     * This field is only used when building multi-tile meshes.
     *
     * @return The width/height size of tile's on the xz-plane. [Limit: >= 0]
     * [Units: vx].
     */
    public int getTileSize() {
        return RecastJNI.rcConfig_tileSize_get(swigCPtr, this);
    }

    /**
     * This value represents the the closest the walkable area of the
     * heightfield should come to the xz-plane AABB of the field. It does not
     * have any impact on the borders around internal obstructions.
     *
     * @param value The size of the non-navigable border around the heightfield.
     * [Limit: >=0] [Units: vx].
     */
    public void setBorderSize(int value) {
        RecastJNI.rcConfig_borderSize_set(swigCPtr, this, value);
    }

    /**
     * This value represents the the closest the walkable area of the
     * heightfield should come to the xz-plane AABB of the field. It does not
     * have any impact on the borders around internal obstructions.
     *
     * @return The size of the non-navigable border around the heightfield.
     * [Limit: >=0] [Units: vx].
     */
    public int getBorderSize() {
        return RecastJNI.rcConfig_borderSize_get(swigCPtr, this);
    }

    /**
     * The minimum value for this parameter depends on the platform's floating
     * point accuracy, with the practical minimum usually around 0.05.
     *
     * @param value The xz-plane cell size to use for fields. [Limit: > 0]
     * [Units: wu].
     */
    public void setCellSize(float value) {
        RecastJNI.rcConfig_cs_set(swigCPtr, this, value);
    }

    /**
     * The minimum value for this parameter depends on the platform's floating
     * point accuracy, with the practical minimum usually around 0.05.
     *
     * @return The xz-plane cell size to use for fields. [Limit: > 0] [Units:
     * wu].
     */
    public float getCellSize() {
        return RecastJNI.rcConfig_cs_get(swigCPtr, this);
    }

    /**
     * The minimum value for this parameter depends on the platform's floating
     * point accuracy, with the practical minimum usually around 0.05.
     *
     * @param value The y-axis cell size to use for fields. [Limit: > 0] [Units:
     * wu].
     */
    public void setCellHeight(float value) {
        RecastJNI.rcConfig_ch_set(swigCPtr, this, value);
    }

    /**
     * The minimum value for this parameter depends on the platform's floating
     * point accuracy, with the practical minimum usually around 0.05.
     *
     * @return The y-axis cell size to use for fields. [Limit: > 0] [Units: wu].
     */
    public float getCellHeight() {
        return RecastJNI.rcConfig_ch_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds of the field's AABB.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcConfig_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds of the field's AABB.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcConfig_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds of the field's AABB.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcConfig_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds of the field's AABB.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcConfig_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     * The practical upper limit for this parameter is usually around 85
     * degrees.
     *
     * @param value The maximum slope that is considered walkable. [Limits: 90 >
     * value >=0] [Units: Degrees].
     */
    public void setWalkableSlopeAngle(float value) {
        RecastJNI.rcConfig_walkableSlopeAngle_set(swigCPtr, this, value);
    }

    /**
     * The practical upper limit for this parameter is usually around 85
     * degrees.
     *
     * @return The maximum slope that is considered walkable. [Limits: 90 >
     * value >=0] [Units: Degrees].
     */
    public float getWalkableSlopeAngle() {
        return RecastJNI.rcConfig_walkableSlopeAngle_get(swigCPtr, this);
    }

    /**
     * Permits detection of overhangs in the source geometry that make the
     * geometry below un-walkable. The value is usually set to the maximum agent
     * height.
     *
     * @param value Minimum floor to 'ceiling' height that will still allow the
     * floor area to be considered walkable. [Limit: >= 3] [Units: vx]
     */
    public void setWalkableHeight(int value) {
        RecastJNI.rcConfig_walkableHeight_set(swigCPtr, this, value);
    }

    /**
     * Permits detection of overhangs in the source geometry that make the
     * geometry below un-walkable. The value is usually set to the maximum agent
     * height.
     *
     * @return Minimum floor to 'ceiling' height that will still allow the floor
     * area to be considered walkable. [Limit: >= 3] [Units: vx]
     */
    public int getWalkableHeight() {
        return RecastJNI.rcConfig_walkableHeight_get(swigCPtr, this);
    }

    /**
     * Allows the mesh to flow over low lying obstructions such as curbs and
     * up/down stairways. The value is usually set to how far up/down an agent
     * can step.
     *
     * @param value Maximum ledge height that is considered to still be
     * traversable. [Limit: >=0] [Units: vx].
     */
    public void setWalkableClimb(int value) {
        RecastJNI.rcConfig_walkableClimb_set(swigCPtr, this, value);
    }

    /**
     * Allows the mesh to flow over low lying obstructions such as curbs and
     * up/down stairways. The value is usually set to how far up/down an agent
     * can step.
     *
     * @return Maximum ledge height that is considered to still be traversable.
     * [Limit: >=0] [Units: vx].
     */
    public int getWalkableClimb() {
        return RecastJNI.rcConfig_walkableClimb_get(swigCPtr, this);
    }

    /**
     * In general, this is the closest any part of the final mesh should get to
     * an obstruction in the source geometry. It is usually set to the maximum
     * agent radius.
     *
     * While a value of zero is legal, it is not recommended and can result in
     * odd edge case issues.
     *
     * @param value The distance to erode/shrink the walkable area of the
     * heightfield away from obstructions. [Limit: >=0] [Units: vx]
     */
    public void setWalkableRadius(int value) {
        RecastJNI.rcConfig_walkableRadius_set(swigCPtr, this, value);
    }

    /**
     * In general, this is the closest any part of the final mesh should get to
     * an obstruction in the source geometry. It is usually set to the maximum
     * agent radius.
     *
     * While a value of zero is legal, it is not recommended and can result in
     * odd edge case issues.
     *
     * @return The distance to erode/shrink the walkable area of the heightfield
     * away from obstructions. [Limit: >=0] [Units: vx]
     */
    public int getWalkableRadius() {
        return RecastJNI.rcConfig_walkableRadius_get(swigCPtr, this);
    }

    /**
     * Extra vertices will be inserted as needed to keep contour edges below
     * this length. A value of zero effectively disables this feature.
     *
     * @param value The maximum allowed length for contour edges along the
     * border of the mesh. [Limit: >=0] [Units: vx].
     */
    public void setMaxEdgeLength(int value) {
        RecastJNI.rcConfig_maxEdgeLen_set(swigCPtr, this, value);
    }

    /**
     * Extra vertices will be inserted as needed to keep contour edges below
     * this length. A value of zero effectively disables this feature.
     *
     * @return The maximum allowed length for contour edges along the border of
     * the mesh. [Limit: >=0] [Units: vx].
     */
    public int getMaxEdgeLength() {
        return RecastJNI.rcConfig_maxEdgeLen_get(swigCPtr, this);
    }

    /**
     * The effect of this parameter only applies to the xz-plane.
     *
     * @param value The maximum distance a simplfied contour's border edges
     * should deviate the original raw contour.
     *
     * [Limit: >=0] [Units: vx]
     *
     */
    public void setMaxSimplificationError(float value) {
        RecastJNI.rcConfig_maxSimplificationError_set(swigCPtr, this, value);
    }

    /**
     * The effect of this parameter only applies to the xz-plane.
     *
     * @return The maximum distance a simplfied contour's border edges should
     * deviate the original raw contour.
     *
     * [Limit: >=0] [Units: vx]
     */
    public float getMaxSimplificationError() {
        return RecastJNI.rcConfig_maxSimplificationError_get(swigCPtr, this);
    }

    /**
     * Any regions that are smaller than this area will be marked as unwalkable.
     * This is useful in removing useless regions that can sometimes form on
     * geometry such as table tops, box tops, etc.
     *
     * @param value The minimum number of cells allowed to form isolated island
     * areas. [Limit: >=0] [Units: vx].
     */
    public void setMinRegionArea(int value) {
        RecastJNI.rcConfig_minRegionArea_set(swigCPtr, this, value);
    }

    /**
     * Any regions that are smaller than this area will be marked as unwalkable.
     * This is useful in removing useless regions that can sometimes form on
     * geometry such as table tops, box tops, etc.
     *
     * @return The minimum number of cells allowed to form isolated island
     * areas. [Limit: >=0] [Units: vx].
     */
    public int getMinRegionArea() {
        return RecastJNI.rcConfig_minRegionArea_get(swigCPtr, this);
    }

    /**
     *
     * @param value Any regions with a span count smaller than this value will,
     * if possible, be merged with larger regions. [Limit: >=0] [Units: vx]
     */
    public void setMergeRegionArea(int value) {
        RecastJNI.rcConfig_mergeRegionArea_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Any regions with a span count smaller than this value will, if
     * possible, be merged with larger regions. [Limit: >=0] [Units: vx]
     */
    public int getMergeRegionArea() {
        return RecastJNI.rcConfig_mergeRegionArea_get(swigCPtr, this);
    }

    /**
     * If the mesh data is to be used to construct a DetourBuilder navigation mesh,
     * then the upper limit is limited to smaller than DT_VERTS_PER_POLYGON.
     *
     * @param value The maximum number of vertices allowed for polygons
     * generated during the contour to polygon conversion process. [Limit: >= 3]
     * @see DetourBuilder#DT_VERTS_PER_POLYGON()
     */
    public void setMaxVerticesPerPoly(int value) {
        RecastJNI.rcConfig_maxVertsPerPoly_set(swigCPtr, this, value);
    }

    /**
     * If the mesh data is to be used to construct a DetourBuilder navigation mesh,
     * then the upper limit is limited to smaller than DT_VERTS_PER_POLYGON.
     *
     * @return The maximum number of vertices allowed for polygons generated
     * during the contour to polygon conversion process. [Limit: >= 3]
     * @see DetourBuilder#DT_VERTS_PER_POLYGON()
     */
    public int getMaxVertsPerPoly() {
        return RecastJNI.rcConfig_maxVertsPerPoly_get(swigCPtr, this);
    }

    /**
     * Sets the sampling distance to use when generating the detail mesh. (For
     * height detail only.) [Limits: 0 or >= 0.9] [Units: wu]
     *
     * @param value
     */
    public void setDetailSampleDistance(float value) {
        RecastJNI.rcConfig_detailSampleDist_set(swigCPtr, this, value);
    }

    /**
     * Sets the sampling distance to use when generating the detail mesh. (For
     * height detail only.) [Limits: 0 or >= 0.9] [Units: wu]
     *
     * @return
     */
    public float getDetailSampleDistance() {
        return RecastJNI.rcConfig_detailSampleDist_get(swigCPtr, this);
    }

    /**
     * The maximum distance the detail mesh surface should deviate from
     * heightfield data.
     *
     * (For height detail only.) [Limit: >=0] [Units: wu]
     *
     * @param value
     */
    public void setDetailSampleMaxError(float value) {
        RecastJNI.rcConfig_detailSampleMaxError_set(swigCPtr, this, value);
    }

    /**
     * The maximum distance the detail mesh surface should deviate from
     * heightfield data.
     *
     * (For height detail only.) [Limit: >=0] [Units: wu]
     *
     * @return
     */
    public float getDetailSampleMaxError() {
        return RecastJNI.rcConfig_detailSampleMaxError_get(swigCPtr, this);
    }
} public class Context {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public Context() {
        this(RecastJNI.new_rcContext__SWIG_1(), true);
    }

    /**
     * Contructor.
     *
     * @param state TRUE if the logging and performance timers should be
     * enabled. [Default: true]
     */
    public Context(boolean state) {
        this(RecastJNI.new_rcContext__SWIG_0(state), true);
    }

    protected Context(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Context obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcContext(swigCPtr);
            }
            swigCPtr = 0;
        }
    }
/**
 * Enables or disables logging.
 * @param state TRUE if logging should be enabled.

 */
    public void enableLog(boolean state) {
        RecastJNI.rcContext_enableLog(swigCPtr, this, state);
    }

    /**
     * Clears all log entries.
     */
    public void resetLog() {
        RecastJNI.rcContext_resetLog(swigCPtr, this);
    }

    /**
     * Logs a message.
     *
     * @param category The category of the message.
     * @param message The formatted message.
     */
    public void log(LogCategory category, String message) {
        RecastJNI.rcContext_log(swigCPtr, this, category.swigValue(), message);
    }
/**
 * Enables or disables the performance timers.
 * @param state TRUE if timers should be enabled.
 */
    public void enableTimer(boolean state) {
        RecastJNI.rcContext_enableTimer(swigCPtr, this, state);
    }

    /**
     * Clears all timers. (Resets all to unused.)
     */
    public void resetTimers() {
        RecastJNI.rcContext_resetTimers(swigCPtr, this);
    }

    /**
     * Starts the specified performance timer.
     *
     * @param label The category of timer.
     */
    public void startTimer(TimerLabel label) {
        RecastJNI.rcContext_startTimer(swigCPtr, this, label.value());
    }

    /**
     * Stops the specified performance timer.
     *
     * @param label The category of the timer.
     */
    public void stopTimer(TimerLabel label) {
        RecastJNI.rcContext_stopTimer(swigCPtr, this, label.value());
    }

    /**
     * Returns the total accumulated time of the specified performance timer.
     *
     * @param label The category of the timer.
     * @return The accumulated time of the timer, or -1 if timers are disabled
     * or the timer has never been started.
     */
    public int getAccumulatedTime(TimerLabel label) {
        return RecastJNI.rcContext_getAccumulatedTime(swigCPtr, this, label.value());
    }
} public class Contour {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * For internal use only.
     */
    public Contour(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Contour obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcContour(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * The simplified contour is a version of the raw contour with all
     * 'unnecessary' vertices removed. Whether a vertex is considered
     * unnecessary depends on the contour build process.
     *
     * The data format is as follows: (x, y, z, r) * numberOfVertices
     *
     * A contour edge is formed by the current and next vertex. The r-value
     * represents region and connection information for the edge.
     *
     * @param value Simplified contour vertex and connection data. [Size: 4 *
     * numberOfVertices].
     */
    public void setVertices(int[] value) {
        SWIGTYPE_p_int v = Converter.convertToSWIGTYPE_p_int(value);
        RecastJNI.rcContour_verts_set(swigCPtr, this, SWIGTYPE_p_int.getCPtr(v));
    }

    /**
     * The simplified contour is a version of the raw contour with all
     * 'unnecessary' vertices removed. Whether a vertex is considered
     * unnecessary depends on the contour build process.
     *
     * The data format is as follows: (x, y, z, r) * numberOfVertices
     *
     * A contour edge is formed by the current and next vertex. The r-value
     * represents region and connection information for the edge.
     *
     * @return Simplified contour vertex and connection data. [Size: 4 *
     * numberOfVertices].
     */
    public int[] getVertices() {
        long cPtr = RecastJNI.rcContour_verts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToInts(cPtr, getNumberOfVertices() * 4);
    }

    /**
     *
     * @param numberOfVertices The number of vertices in the simplified contour.
     */
    public void setNumberOfVertices(int numberOfVertices) {
        RecastJNI.rcContour_nverts_set(swigCPtr, this, numberOfVertices);
    }

    /**
     *
     * @return The number of vertices in the simplified contour.
     */
    public int getNumberOfVertices() {
        return RecastJNI.rcContour_nverts_get(swigCPtr, this);
    }

    /**
     * The simplified contour is a version of the raw contour with all
     * 'unnecessary' vertices removed. Whether a vertex is considered
     * unnecessary depends on the contour build process.
     *
     * The data format is as follows: (x, y, z, r) * numberOfRawVertices
     *
     * A contour edge is formed by the current and next vertex. The r-value
     * represents region and connection information for the edge.
     *
     * @param value Raw contour vertex and connection data. [Size: 4 *
     * numberOfRawVertices].
     */
    public void setRawVertices(int[] value) {
        SWIGTYPE_p_int v = Converter.convertToSWIGTYPE_p_int(value);
        RecastJNI.rcContour_rverts_set(swigCPtr, this, SWIGTYPE_p_int.getCPtr(v));
    }

    /**
     * The simplified contour is a version of the raw contour with all
     * 'unnecessary' vertices removed. Whether a vertex is considered
     * unnecessary depends on the contour build process.
     *
     * The data format is as follows: (x, y, z, r) * numberOfRawVertices
     *
     * A contour edge is formed by the current and next vertex. The r-value
     * represents region and connection information for the edge.
     *
     * @return Raw contour vertex and connection data. [Size: 4 *
     * numberOfRawVertices].
     */
    public int[] getRawVertices() {
        long cPtr = RecastJNI.rcContour_rverts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToInts(cPtr, getNumberOfRawVertices() * 4);
    }

    /**
     *
     * @param value The number of vertices in the raw contour.
     */
    public void setNumberOfRawVertices(int value) {
        RecastJNI.rcContour_nrverts_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices in the raw contour.
     */
    public int getNumberOfRawVertices() {
        return RecastJNI.rcContour_nrverts_get(swigCPtr, this);
    }

    /**
     *
     * @param value The region id of the contour.
     */
    public void setRegionID(int value) {
        RecastJNI.rcContour_reg_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The region id of the contour.
     */
    public int getRegionID() {
        return RecastJNI.rcContour_reg_get(swigCPtr, this);
    }

    /**
     *
     * @param value The area id of the contour.
     */
    public void setArea(short value) {
        RecastJNI.rcContour_area_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The area id of the contour.
     */
    public short getArea() {
        return RecastJNI.rcContour_area_get(swigCPtr, this);
    }
} public class ContourSet {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a contour set object using the Recast allocator.
     */
    public ContourSet() {
        swigCPtr = RecastJNI.rcAllocContourSet();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected ContourSet(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(ContourSet obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreeContourSet(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

//    /**
//     * - not done yet
//     *
//     * @param value An array of the contours in the set.
//     */
//    public void setContours(Contour value) {
//        RecastJNI.rcContourSet_conts_set(swigCPtr, this, Contour.getCPtr(value), value);
//    }
    /**
     *
     * @return An array of the contours in the set.
     */
    public Contour[] getContours() {
        long cPtr = RecastJNI.rcContourSet_conts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        Contour[] contours = new Contour[getNumberOfContours()];
        for (int i = 0; i < contours.length; i++) {
            contours[i] = new Contour(cPtr + i, false);
        }
        return contours;
    }

//    /**
//     *
//     * @param value The number of contours in the set.
//     */
//    public void setNumberOfContours(int value) {
//        RecastJNI.rcContourSet_nconts_set(swigCPtr, this, value);
//    }
    /**
     *
     * @return The number of contours in the set.
     */
    protected int getNumberOfContours() {
        return RecastJNI.rcContourSet_nconts_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds in world space.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcContourSet_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds in world space.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcContourSet_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds in world space.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcContourSet_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds in world space.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcContourSet_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The size of each cell. (On the xz-plane.)
     */
    public void setCellSize(float value) {
        RecastJNI.rcContourSet_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The size of each cell. (On the xz-plane.)
     */
    public float getCellSize() {
        return RecastJNI.rcContourSet_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public void setCellHeight(float value) {
        RecastJNI.rcContourSet_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public float getCellHeight() {
        return RecastJNI.rcContourSet_ch_get(swigCPtr, this);
    }

    /**
     *
     * @param value The width of the set. (Along the x-axis in cell units.)
     */
    public void setWidth(int value) {
        RecastJNI.rcContourSet_width_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of the set. (Along the x-axis in cell units.)
     */
    public int getWidth() {
        return RecastJNI.rcContourSet_width_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of the set. (Along the z-axis in cell units.)
     */
    public void setHeight(int value) {
        RecastJNI.rcContourSet_height_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the set. (Along the z-axis in cell units.)
     */
    public int getHeight() {
        return RecastJNI.rcContourSet_height_get(swigCPtr, this);
    }

    /**
     *
     * @param value The AABB border size used to generate the source data from
     * which the contours were derived.
     */
    public void setBorderSize(int value) {
        RecastJNI.rcContourSet_borderSize_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The AABB border size used to generate the source data from which
     * the contours were derived.
     */
    public int getBorderSize() {
        return RecastJNI.rcContourSet_borderSize_get(swigCPtr, this);
    }
} public class Heightfield {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a heightfield object using the Recast allocator.
     */
    public Heightfield() {
        swigCPtr = RecastJNI.rcAllocHeightfield();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected Heightfield(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Heightfield obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreeHeightField(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The width of the heightfield. (Along the x-axis in cell
     * units.)
     */
    public void setWidth(int value) {
        RecastJNI.rcHeightfield_width_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of the heightfield. (Along the x-axis in cell units.)
     */
    public int getWidth() {
        return RecastJNI.rcHeightfield_width_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of the heightfield. (Along the z-axis in cell
     * units.)
     */
    public void setHeight(int value) {
        RecastJNI.rcHeightfield_height_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the heightfield. (Along the z-axis in cell units.)
     */
    public int getHeight() {
        return RecastJNI.rcHeightfield_height_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds in world space.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcHeightfield_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds in world space.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcHeightfield_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds in world space.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcHeightfield_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds in world space.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcHeightfield_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The size of each cell. (On the xz-plane.)
     */
    public void setCellSize(float value) {
        RecastJNI.rcHeightfield_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The size of each cell. (On the xz-plane.)
     */
    public float getCellSize() {
        return RecastJNI.rcHeightfield_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public void setCellHeight(float value) {
        RecastJNI.rcHeightfield_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public float getCellHeight() {
        return RecastJNI.rcHeightfield_ch_get(swigCPtr, this);
    }

    /**
     *
     * @return Heightfield of spans (width*height).
     */
    public Span[] getSpans() {
        long cPtr = RecastJNI.rcHeightfield_spans_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        int length = getHeight() * getWidth();
        Span[] spans = new Span[length];
        for (int i = 0; i < length; i++) {
            spans[i] = new Span(cPtr + i, false);
        }
        return spans;
    }
    /**
     * Visual representation of solid heightfield. Created for debugging
     * purposes.
     *
     * @return
     */
    /*public Mesh drawHeightfieldSolid() {
     Mesh mesh = new Mesh();
     mesh.setMode(Mesh.Mode.Lines);

     Vector3f origin = getMinBounds();
     float cellSize = getCellSize();
     float cellHeight = getCellHeight();
     int width = getWidth();
     int height = getHeight();

     List<int[]> indices = new LinkedList<>();
     List<Vector3f[]> vertices = new LinkedList<>();
     System.out.println(height);
     System.out.println(width);
     for (int y = 0; y < height; y++) {
     for (int x = 0; x < width; x++) {
     float fx = origin.getX() + x * cellSize;
     float fz = origin.getZ() + y * cellSize;
     Span s = getSpans()[x + y * width];
     int i = 0;
     while (s != null) {
     Vector3f min = new Vector3f(fx, origin.getY() + s.getMinSpanLimit() * cellHeight, fz);
     Vector3f max = new Vector3f(fx + cellSize, origin.getY() + s.getMaxSpanLimit() * cellHeight, fz + cellSize);
                    Mesh mesh1 = GraphicHelper.lineBox(min, max);
     indices.add(GraphicHelper.getIndices(mesh1));
     vertices.add(GraphicHelper.getVertices(mesh1));
     s = s.getNext();
     i++;
     }
     }
     }
     for (Vector3f[] vector3fs : vertices) {
     mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vector3fs));
     }
     for (int[] ints : indices) {
     mesh.setBuffer(VertexBuffer.Type.Index, 2, BufferUtils.createIntBuffer(ints));
     }
     mesh.updateCounts();
     mesh.updateBound();
     return mesh;
     }*/
} public class HeightfieldLayer {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public HeightfieldLayer() {
        this(RecastJNI.new_rcHeightfieldLayer(), true);
    }

    public HeightfieldLayer(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(HeightfieldLayer obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcHeightfieldLayer(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param minBounds The minimum bounds in world space.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcHeightfieldLayer_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds in world space.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcHeightfieldLayer_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds in world space.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcHeightfieldLayer_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds in world space.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcHeightfieldLayer_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The size of each cell. (On the xz-plane.)
     */
    public void setCellSize(float value) {
        RecastJNI.rcHeightfieldLayer_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The size of each cell. (On the xz-plane.)
     */
    public float getCellSize() {
        return RecastJNI.rcHeightfieldLayer_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public void setCellHeight(float value) {
        RecastJNI.rcHeightfieldLayer_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public float getCellHeight() {
        return RecastJNI.rcHeightfieldLayer_ch_get(swigCPtr, this);
    }

    /**
     *
     * @param value The width of the heightfield. (Along the x-axis in cell
     * units.)
     */
    public void setWidth(int value) {
        RecastJNI.rcHeightfieldLayer_width_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The width of the heightfield. (Along the x-axis in cell units.)
     */
    public int getWidth() {
        return RecastJNI.rcHeightfieldLayer_width_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of the heightfield. (Along the z-axis in cell
     * units.)
     */
    public void setHeight(int value) {
        RecastJNI.rcHeightfieldLayer_height_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of the heightfield. (Along the z-axis in cell units.)
     */
    public int getHeight() {
        return RecastJNI.rcHeightfieldLayer_height_get(swigCPtr, this);
    }

    /**
     *
     * @param value The minimum x-bounds of usable data.
     */
    public void setMinX(int value) {
        RecastJNI.rcHeightfieldLayer_minx_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The minimum x-bounds of usable data.
     */
    public int getMinX() {
        return RecastJNI.rcHeightfieldLayer_minx_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum x-bounds of usable data.
     */
    public void setMaxX(int value) {
        RecastJNI.rcHeightfieldLayer_maxx_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum x-bounds of usable data.
     */
    public int getMaxX() {
        return RecastJNI.rcHeightfieldLayer_maxx_get(swigCPtr, this);
    }

    /**
     *
     * @param value The minimum y-bounds of usable data. (Along the z-axis.)
     */
    public void setMinY(int value) {
        RecastJNI.rcHeightfieldLayer_miny_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The minimum y-bounds of usable data. (Along the z-axis.)
     */
    public int getMinY() {
        return RecastJNI.rcHeightfieldLayer_miny_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum y-bounds of usable data. (Along the z-axis.)
     */
    public void setMaxY(int value) {
        RecastJNI.rcHeightfieldLayer_maxy_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum y-bounds of usable data. (Along the z-axis.)
     */
    public int getMaxY() {
        return RecastJNI.rcHeightfieldLayer_maxy_get(swigCPtr, this);
    }

    /**
     *
     * @param value The minimum height bounds of usable data. (Along the
     * y-axis.)
     */
    public void setMinHeight(int value) {
        RecastJNI.rcHeightfieldLayer_hmin_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The minimum height bounds of usable data. (Along the y-axis.)
     */
    public int getMinHeight() {
        return RecastJNI.rcHeightfieldLayer_hmin_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum height bounds of usable data. (Along the
     * y-axis.)
     */
    public void setMaxHeight(int value) {
        RecastJNI.rcHeightfieldLayer_hmax_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum height bounds of usable data. (Along the y-axis.)
     */
    public int getMaxHeight() {
        return RecastJNI.rcHeightfieldLayer_hmax_get(swigCPtr, this);
    }

    /**
     *
     * @param heights The heightfield. [Size: (width - borderSize*2) * (h -
     * borderSize*2)].
     */
    public void setHeights(char[] heights) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(heights);
        RecastJNI.rcHeightfieldLayer_heights_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @param borderSize
     * @return The heightfield. [Size: (width - borderSize*2) * (h -
     * borderSize*2)].
     */
    public char[] getHeights(int borderSize) {
        long cPtr = RecastJNI.rcHeightfieldLayer_heights_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        int count = (getWidth() - borderSize * 2) * (getHeight() - borderSize * 2);
        return Converter.convertToChars(cPtr, count);
    }

    /**
     *
     * @param areas Area ids.
     */
    public void setAreas(char[] areas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(areas);
        RecastJNI.rcHeightfieldLayer_areas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @param borderSize
     * @return Area ids.
     * @see Heightfield#getHeights
     */
    public char[] getAreas(int borderSize) {
        long cPtr = RecastJNI.rcHeightfieldLayer_areas_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        int count = (getWidth() - borderSize * 2) * (getHeight() - borderSize * 2);
        return Converter.convertToChars(cPtr, count);
    }

    /**
     *
     * @param connections Packed neighbor connection information.
     */
    public void setConnections(char[] connections) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(connections);
        RecastJNI.rcHeightfieldLayer_cons_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @param borderSize
     * @return Packed neighbor connection information.
     */
    public char[] getConnections(int borderSize) {
        long cPtr = RecastJNI.rcHeightfieldLayer_cons_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        int count = (getWidth() - borderSize * 2) * (getHeight() - borderSize * 2);
        return Converter.convertToChars(cPtr, count);
    }
} public class HeightfieldLayerSet {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a heightfield layer set using the Recast allocator.
     */
    public HeightfieldLayerSet() {
        swigCPtr = RecastJNI.rcAllocHeightfieldLayerSet();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected HeightfieldLayerSet(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(HeightfieldLayerSet obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreeHeightfieldLayerSet(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

//    /**
//     * -not done yet
//     *
//     * @param value The layers in the set.
//     */
//    public void setLayers(HeightfieldLayer value) {
//        RecastJNI.rcHeightfieldLayerSet_layers_set(swigCPtr, this, HeightfieldLayer.getCPtr(value), value);
//    }
    /**
     *
     * @return The layers in the set.
     */
    public HeightfieldLayer[] getLayers() {
        long cPtr = RecastJNI.rcHeightfieldLayerSet_layers_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        HeightfieldLayer[] heightfieldLayers = new HeightfieldLayer[getNumberOfLayers()];
        for (int i = 0; i < heightfieldLayers.length; i++) {
            heightfieldLayers[i] = new HeightfieldLayer(cPtr + i, false);
        }
        return heightfieldLayers;
    }

//    /**
//     *
//     * @param value The number of layers in the set.
//     */
//    public void setNumberOfLayers(int value) {
//        RecastJNI.rcHeightfieldLayerSet_nlayers_set(swigCPtr, this, value);
//    }
    /**
     *
     * @return The number of layers in the set.
     */
    protected int getNumberOfLayers() {
        return RecastJNI.rcHeightfieldLayerSet_nlayers_get(swigCPtr, this);
    }
} public class PolyMesh {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a polygon mesh object using the Recast allocator.
     */
    public PolyMesh() {
        swigCPtr = RecastJNI.rcAllocPolyMesh();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    public PolyMesh(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(PolyMesh obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            delete();
        } finally {
            super.finalize();
        }
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreePolyMesh(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param vertices The mesh vertices.
     */
    public void setVertices(Vector3f[] vertices) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(vertices);
        RecastJNI.rcPolyMesh_verts_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The mesh vertices.
     */
    public Vector3f[] getVertices() {
        long cPtr = RecastJNI.rcPolyMesh_verts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr, getNumberOfVertices());
    }

    /**
     *
     * @param polygons Polygon and neighbor data. [Length: maxNumberOfPolygons *
     * 2 * numberOfVerticesPerPolygon].
     */
    public void setPolygons(short[] polygons) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(polygons);
        RecastJNI.rcPolyMesh_polys_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Polygon and neighbor data. [Length: maxNumberOfPolygons * 2 *
     * numberOfVerticesPerPolygon].
     */
    public short[] getPolygons() {
        long cPtr = RecastJNI.rcPolyMesh_polys_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToShorts(cPtr, getMaxNumberOfPolygons() * 2 * getNumberOfVerticesPerPolygon());
    }

    /**
     *
     * @param regionIDs The region id assigned to each polygon.
     */
    public void setRegionIDs(short[] regionIDs) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(regionIDs);
        RecastJNI.rcPolyMesh_regs_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The region id assigned to each polygon.
     */
    public short[] getRegionIDs() {
        long cPtr = RecastJNI.rcPolyMesh_regs_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToShorts(cPtr, getMaxNumberOfPolygons());
    }

    /**
     *
     * @param flags The user defined flags for each polygon.
     */
    public void setFlags(short[] flags) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(flags);
        RecastJNI.rcPolyMesh_flags_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return The user defined flags for each polygon.
     */
    public short[] getFlags() {
        long cPtr = RecastJNI.rcPolyMesh_flags_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToShorts(cPtr, getMaxNumberOfPolygons());
    }

    /**
     *
     * @param areas The area id assigned to each polygon.
     *
     * The standard build process assigns the value of RC_WALKABLE_AREA to all
     * walkable polygons. This value can then be changed to meet user
     * requirements.
     */
    public void setAreas(char[] areas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(areas);
        RecastJNI.rcPolyMesh_areas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return The area id assigned to each polygon.
     *
     * The standard build process assigns the value of RC_WALKABLE_AREA to all
     * walkable polygons. This value can then be changed to meet user
     * requirements.
     */
    public char[] getAreas() {
        long cPtr = RecastJNI.rcPolyMesh_areas_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getMaxNumberOfPolygons());
    }

    /**
     *
     * @param value The number of vertices.
     */
    public void setNumberOfVertices(int value) {
        RecastJNI.rcPolyMesh_nverts_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices.
     */
    public int getNumberOfVertices() {
        return RecastJNI.rcPolyMesh_nverts_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of polygons.
     */
    public void setNumberOfPolygons(int value) {
        RecastJNI.rcPolyMesh_npolys_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of polygons.
     */
    public int getNumberOfPolygons() {
        return RecastJNI.rcPolyMesh_npolys_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of allocated polygons.
     */
    public void setMaxNumberOfPolygons(int value) {
        RecastJNI.rcPolyMesh_maxpolys_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of allocated polygons.
     */
    public int getMaxNumberOfPolygons() {
        return RecastJNI.rcPolyMesh_maxpolys_get(swigCPtr, this);
    }

    /**
     *
     * @param value The maximum number of vertices per polygon.
     */
    public void setNumberOfVerticesPerPolygon(int value) {
        RecastJNI.rcPolyMesh_nvp_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The maximum number of vertices per polygon.
     */
    public int getNumberOfVerticesPerPolygon() {
        return RecastJNI.rcPolyMesh_nvp_get(swigCPtr, this);
    }

    /**
     *
     * @param minBounds The minimum bounds in world space.
     */
    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.rcPolyMesh_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The minimum bounds in world space.
     */
    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.rcPolyMesh_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param maxBounds The maximum bounds in world space.
     */
    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.rcPolyMesh_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     *
     * @return The maximum bounds in world space.
     */
    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.rcPolyMesh_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    /**
     *
     * @param value The size of each cell. (On the xz-plane.)
     */
    public void setCellSize(float value) {
        RecastJNI.rcPolyMesh_cs_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The size of each cell. (On the xz-plane.)
     */
    public float getCellSize() {
        return RecastJNI.rcPolyMesh_cs_get(swigCPtr, this);
    }

    /**
     *
     * @param value The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public void setCellHeight(float value) {
        RecastJNI.rcPolyMesh_ch_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The height of each cell. (The minimum increment along the
     * y-axis.)
     */
    public float getCellHeight() {
        return RecastJNI.rcPolyMesh_ch_get(swigCPtr, this);
    }

    /**
     *
     * @param value The AABB border size used to generate the source data from
     * which the mesh was derived.
     */
    public void setBorderSize(int value) {
        RecastJNI.rcPolyMesh_borderSize_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The AABB border size used to generate the source data from which
     * the mesh was derived.
     */
    public int getBorderSize() {
        return RecastJNI.rcPolyMesh_borderSize_get(swigCPtr, this);
    }
} public class PolyMeshDetail {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Allocates a detail mesh object using the Recast allocator.
     */
    public PolyMeshDetail() {
        swigCPtr = RecastJNI.rcAllocPolyMeshDetail();
        swigCMemOwn = (swigCPtr == 0) ? false : true;
    }

    protected PolyMeshDetail(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(PolyMeshDetail obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.rcFreePolyMeshDetail(swigCPtr, this);
            }
            swigCPtr = 0;
        }
    }

    /**
     * [(baseVertIndex, vertCount, baseTriIndex, triCount) * numberOfMeshes]
     *
     * Maximum number of vertices per sub-mesh: 127 Maximum number of triangles
     * per sub-mesh: 255
     *
     * The sub-meshes are stored in the same order as the polygons from the
     * rcPolyMesh they represent. E.g. PolyMeshDetail sub-mesh 5 is associated
     * with PolyMesh polygon 5.
     *
     * @param meshes The sub-mesh data. [Size: 4*numberOfMeshes].
     */
    public void setMeshes(int[] meshes) {
        SWIGTYPE_p_unsigned_int value = null;//FIXME:
        RecastJNI.rcPolyMeshDetail_meshes_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    /**
     * [(baseVertIndex, vertCount, baseTriIndex, triCount) * numberOfMeshes]
     *
     * Maximum number of vertices per sub-mesh: 127 Maximum number of triangles
     * per sub-mesh: 255
     *
     * The sub-meshes are stored in the same order as the polygons from the
     * rcPolyMesh they represent. E.g. PolyMeshDetail sub-mesh 5 is associated
     * with PolyMesh polygon 5.
     *
     * @return The sub-mesh data. [Size: 4*numberOfMeshes].
     */
    public int[] getMeshes() {
        long cPtr = RecastJNI.rcPolyMeshDetail_meshes_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToInts(cPtr, getNumberOfMeshes());
    }

    /**
     * The vertices are grouped by sub-mesh and will contain duplicates since
     * each sub-mesh is independently defined.
     *
     * The first group of vertices for each sub-mesh are in the same order as
     * the vertices for the sub-mesh's associated PolyMesh polygon. These
     * vertices are followed by any additional detail vertices. So it the
     * associated polygon has 5 vertices, the sub-mesh will have a minimum of 5
     * vertices and the first 5 vertices will be equivalent to the 5 polygon
     * vertices.
     *
     * @param vertices The mesh vertices.
     */
    public void setVertices(Vector3f[] vertices) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(vertices);
        RecastJNI.rcPolyMeshDetail_verts_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    /**
     * The vertices are grouped by sub-mesh and will contain duplicates since
     * each sub-mesh is independently defined.
     *
     * The first group of vertices for each sub-mesh are in the same order as
     * the vertices for the sub-mesh's associated PolyMesh polygon. These
     * vertices are followed by any additional detail vertices. So it the
     * associated polygon has 5 vertices, the sub-mesh will have a minimum of 5
     * vertices and the first 5 vertices will be equivalent to the 5 polygon
     * vertices.
     *
     * @return The mesh vertices.
     */
    public Vector3f[] getVertices() {
        long cPtr = RecastJNI.rcPolyMeshDetail_verts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr, getNumberOfVertices());
    }

    /**
     * [(vertIndexA, vertIndexB, vertIndexC, flags) * numberOfTriangles]
     *
     * The triangles are grouped by sub-mesh.
     *
     * Vertex Indices
     *
     * The vertex indices in the triangle array are local to the sub-mesh, not
     * global. To translate into an global index in the vertices array, the
     * values must be offset by the sub-mesh's base vertex index.
     *
     * Example: If the baseVertexIndex for the sub-mesh is 5 and the triangle
     * entry is (4, 8, 7, 0), then the actual indices for the vertices are (4 +
     * 5, 8 + 5, 7 + 5).
     *
     * Flags
     *
     * The flags entry indicates which edges are internal and which are external
     * to the sub-mesh. Internal edges connect to other triangles within the
     * same sub-mesh. External edges represent portals to other sub-meshes or
     * the null region.
     *
     * Each flag is stored in a 2-bit position. Where position 0 is the lowest
     * 2-bits and position 4 is the highest 2-bits:
     *
     * Position 0: Edge AB (>> 0) Position 1: Edge BC (>> 2) Position 2: Edge CA
     * (>> 4) Position 4: Unused
     *
     * @param triangles The mesh triangles. [Size: 4*numberOfTriangles].
     */
    public void setTriangles(char[] triangles) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(triangles);
        RecastJNI.rcPolyMeshDetail_tris_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     * [(vertIndexA, vertIndexB, vertIndexC, flags) * numberOfTriangles]
     *
     * The triangles are grouped by sub-mesh.
     *
     * Vertex Indices
     *
     * The vertex indices in the triangle array are local to the sub-mesh, not
     * global. To translate into an global index in the vertices array, the
     * values must be offset by the sub-mesh's base vertex index.
     *
     * Example: If the baseVertexIndex for the sub-mesh is 5 and the triangle
     * entry is (4, 8, 7, 0), then the actual indices for the vertices are (4 +
     * 5, 8 + 5, 7 + 5).
     *
     * Flags
     *
     * The flags entry indicates which edges are internal and which are external
     * to the sub-mesh. Internal edges connect to other triangles within the
     * same sub-mesh. External edges represent portals to other sub-meshes or
     * the null region.
     *
     * Each flag is stored in a 2-bit position. Where position 0 is the lowest
     * 2-bits and position 4 is the highest 2-bits:
     *
     * Position 0: Edge AB (>> 0) Position 1: Edge BC (>> 2) Position 2: Edge CA
     * (>> 4) Position 4: Unused
     *
     * @return The mesh triangles. [Size: 4*numberOfTriangles].
     */
    public char[] getTriangles() {
        long cPtr = RecastJNI.rcPolyMeshDetail_tris_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getNumberOfTriangles());
    }

    /**
     *
     * @param value The number of sub-meshes defined by meshes.
     */
    public void setNumberOfMeshes(int value) {
        RecastJNI.rcPolyMeshDetail_nmeshes_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of sub-meshes defined by meshes.
     */
    public int getNumberOfMeshes() {
        return RecastJNI.rcPolyMeshDetail_nmeshes_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of vertices.
     */
    public void setNumberOfVertices(int value) {
        RecastJNI.rcPolyMeshDetail_nverts_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of vertices.
     */
    public int getNumberOfVertices() {
        return RecastJNI.rcPolyMeshDetail_nverts_get(swigCPtr, this);
    }

    /**
     *
     * @param value The number of triangles.
     */
    public void setNumberOfTriangles(int value) {
        RecastJNI.rcPolyMeshDetail_ntris_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The number of triangles.
     */
    public int getNumberOfTriangles() {
        return RecastJNI.rcPolyMeshDetail_ntris_get(swigCPtr, this);
    }

    /**
     * Visual representation of mesh. Created for debugging purposes.
     *
     * @return
     */
    public Mesh createVisualMesh() {
        Mesh mesh = new Mesh();

        return mesh;
    }
} public class Span {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    /**
     * Internal use only.
     */
    protected Span(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(Span obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_rcSpan(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value The lower limit of the span. [Limit: smaller than
     * maxSpanLimit].
     * @see Span#getMaxSpanLimit()
     */
    public void setMinSpanLimit(long value) {
        RecastJNI.rcSpan_smin_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The lower limit of the span. [Limit: smaller than maxSpanLimit].
     * @see Span#getMaxSpanLimit()
     */
    public long getMinSpanLimit() {
        return RecastJNI.rcSpan_smin_get(swigCPtr, this);
    }

    /**
     *
     * @param value The upper limit of the span. [Limit: smaller than
     * RC_SPAN_MAX_HEIGHT].
     * @see RecastBuilder#RC_SPAN_MAX_HEIGHT()
     */
    public void setMaxSpanLimit(long value) {
        RecastJNI.rcSpan_smax_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The upper limit of the span. [Limit: smaller than
     * RC_SPAN_MAX_HEIGHT].
     * @see RecastBuilder#RC_SPAN_MAX_HEIGHT()
     */
    public long getMaxSpanLimit() {
        return RecastJNI.rcSpan_smax_get(swigCPtr, this);
    }

    /**
     *
     * @param value The area id assigned to the span.
     */
    public void setArea(long value) {
        RecastJNI.rcSpan_area_set(swigCPtr, this, value);
    }

    /**
     *
     * @return The area id assigned to the span.
     */
    public long getArea() {
        return RecastJNI.rcSpan_area_get(swigCPtr, this);
    }

    /**
     *
     * @param value The next span higher up in column.
     */
    public void setNext(Span value) {
        RecastJNI.rcSpan_next_set(swigCPtr, this, Span.getCPtr(value), value);
    }

    /**
     *
     * @return The next span higher up in column.
     */
    public Span getNext() {
        long cPtr = RecastJNI.rcSpan_next_get(swigCPtr, this);
        return (cPtr == 0) ? null : new Span(cPtr, false);
    }

    @Override
    public String toString() {
        return "Span{ area=" + getArea() + "; minSpanLimit=" + getMinSpanLimit() + "; maxSpanLimit=" + getMaxSpanLimit() + '}';
    }
} public class CompressedTile {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public CompressedTile() {
        this(RecastJNI.new_dtCompressedTile(), true);
    }

    public CompressedTile(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(CompressedTile obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtCompressedTile(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     *
     * @param value Counter describing modifications to the tile.
     */
    public void setSalt(long value) {
        RecastJNI.dtCompressedTile_salt_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Counter describing modifications to the tile. F
     */
    public long getSalt() {
        return RecastJNI.dtCompressedTile_salt_get(swigCPtr, this);
    }

    public void setHeader(TileCacheLayerHeader value) {
        RecastJNI.dtCompressedTile_header_set(swigCPtr, this, TileCacheLayerHeader.getCPtr(value), value);
    }

    public TileCacheLayerHeader getHeader() {
        long cPtr = RecastJNI.dtCompressedTile_header_get(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheLayerHeader(cPtr, false);
    }

    public void setCompressed(char[] compressed) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(compressed);
        RecastJNI.dtCompressedTile_compressed_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getCompressed() {
        long cPtr = RecastJNI.dtCompressedTile_compressed_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getCompressedSize());
    }

    public void setCompressedSize(int value) {
        RecastJNI.dtCompressedTile_compressedSize_set(swigCPtr, this, value);
    }

    public int getCompressedSize() {
        return RecastJNI.dtCompressedTile_compressedSize_get(swigCPtr, this);
    }

    public void setData(char[] data) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        RecastJNI.dtCompressedTile_data_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getData() {
        long cPtr = RecastJNI.dtCompressedTile_data_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getDataSize());
    }

    public void setDataSize(int value) {
        RecastJNI.dtCompressedTile_dataSize_set(swigCPtr, this, value);
    }

    public int getDataSize() {
        return RecastJNI.dtCompressedTile_dataSize_get(swigCPtr, this);
    }

    public void setFlags(long value) {
        RecastJNI.dtCompressedTile_flags_set(swigCPtr, this, value);
    }

    public long getFlags() {
        return RecastJNI.dtCompressedTile_flags_get(swigCPtr, this);
    }

    public void setNext(CompressedTile value) {
        RecastJNI.dtCompressedTile_next_set(swigCPtr, this, CompressedTile.getCPtr(value), value);
    }

    public CompressedTile getNext() {
        long cPtr = RecastJNI.dtCompressedTile_next_get(swigCPtr, this);
        return (cPtr == 0) ? null : new CompressedTile(cPtr, false);
    }
} public class TileCache {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCache() {
        this(RecastJNI.new_dtTileCache(), true);
    }

    public TileCache(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCache obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCache(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public TileCacheAlloc getAlloc() {
        long cPtr = RecastJNI.dtTileCache_getAlloc(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheAlloc(cPtr, false);
    }

    public TileCacheCompressor getCompressor() {
        long cPtr = RecastJNI.dtTileCache_getCompressor(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheCompressor(cPtr, false);
    }

    public TileCacheParams getParams() {
        long cPtr = RecastJNI.dtTileCache_getParams(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheParams(cPtr, false);
    }

    public int getTileCount() {
        return RecastJNI.dtTileCache_getTileCount(swigCPtr, this);
    }

    public CompressedTile getTile(int i) {
        long cPtr = RecastJNI.dtTileCache_getTile(swigCPtr, this, i);
        return (cPtr == 0) ? null : new CompressedTile(cPtr, false);
    }

    public int getObstacleCount() {
        return RecastJNI.dtTileCache_getObstacleCount(swigCPtr, this);
    }

    public TileCacheObstacle getObstacle(int i) {
        long cPtr = RecastJNI.dtTileCache_getObstacle(swigCPtr, this, i);
        return (cPtr == 0) ? null : new TileCacheObstacle(cPtr, false);
    }

    public TileCacheObstacle getObstacleByRef(long ref) {
        long cPtr = RecastJNI.dtTileCache_getObstacleByRef(swigCPtr, this, ref);
        return (cPtr == 0) ? null : new TileCacheObstacle(cPtr, false);
    }

    public long getObstacleRef(TileCacheObstacle obmin) {
        return RecastJNI.dtTileCache_getObstacleRef(swigCPtr, this, TileCacheObstacle.getCPtr(obmin), obmin);
    }

    public long init(TileCacheParams params, TileCacheAlloc talloc, TileCacheCompressor tcomp, TileCacheMeshProcess tmproc) {
        return RecastJNI.dtTileCache_init(swigCPtr, this, TileCacheParams.getCPtr(params), params, TileCacheAlloc.getCPtr(talloc), talloc, TileCacheCompressor.getCPtr(tcomp), tcomp, TileCacheMeshProcess.getCPtr(tmproc), tmproc);
    }

    public int[] getTilesAt(int tx, int ty, int[] tiles, int maxTiles) {
        SWIGTYPE_p_unsigned_int value = Converter.convertToSWIGTYPE_p_unsigned_int(tiles);
        int count = RecastJNI.dtTileCache_getTilesAt(swigCPtr, this, tx, ty, SWIGTYPE_p_unsigned_int.getCPtr(value), maxTiles);
        return Converter.convertToInts(SWIGTYPE_p_unsigned_int.getCPtr(value), count);
    }

    public CompressedTile getTileAt(int tx, int ty, int tlayer) {
        long cPtr = RecastJNI.dtTileCache_getTileAt(swigCPtr, this, tx, ty, tlayer);
        return (cPtr == 0) ? null : new CompressedTile(cPtr, false);
    }

    public long getTileRef(CompressedTile tile) {
        return RecastJNI.dtTileCache_getTileRef(swigCPtr, this, CompressedTile.getCPtr(tile), tile);
    }

    public CompressedTile getTileByRef(long ref) {
        long cPtr = RecastJNI.dtTileCache_getTileByRef(swigCPtr, this, ref);
        return (cPtr == 0) ? null : new CompressedTile(cPtr, false);
    }

    public long addTile(char[] data, int dataSize, short flags, int[] result) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(data);
        SWIGTYPE_p_unsigned_int result1 = Converter.convertToSWIGTYPE_p_unsigned_int(result);
        return RecastJNI.dtTileCache_addTile(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value), dataSize, flags, SWIGTYPE_p_unsigned_int.getCPtr(result1));
    }

    public long removeTile(long ref, SWIGTYPE_p_p_unsigned_char data, SWIGTYPE_p_int dataSize) {
        return RecastJNI.dtTileCache_removeTile(swigCPtr, this, ref, SWIGTYPE_p_p_unsigned_char.getCPtr(data), SWIGTYPE_p_int.getCPtr(dataSize));
    }

    public long addObstacle(SWIGTYPE_p_float pos, float radius, float height, SWIGTYPE_p_unsigned_int result) {
        return RecastJNI.dtTileCache_addObstacle(swigCPtr, this, SWIGTYPE_p_float.getCPtr(pos), radius, height, SWIGTYPE_p_unsigned_int.getCPtr(result));
    }

    public long removeObstacle(long ref) {
        return RecastJNI.dtTileCache_removeObstacle(swigCPtr, this, ref);
    }

    public long queryTiles(SWIGTYPE_p_float bmin, SWIGTYPE_p_float bmax, SWIGTYPE_p_unsigned_int results, SWIGTYPE_p_int resultCount, int maxResults) {
        return RecastJNI.dtTileCache_queryTiles(swigCPtr, this, SWIGTYPE_p_float.getCPtr(bmin), SWIGTYPE_p_float.getCPtr(bmax), SWIGTYPE_p_unsigned_int.getCPtr(results), SWIGTYPE_p_int.getCPtr(resultCount), maxResults);
    }

    public long update(float arg0, NavMesh navmesh) {
        return RecastJNI.dtTileCache_update(swigCPtr, this, arg0, NavMesh.getCPtr(navmesh), navmesh);
    }

    public long buildNavMeshTilesAt(int tx, int ty, NavMesh navmesh) {
        return RecastJNI.dtTileCache_buildNavMeshTilesAt(swigCPtr, this, tx, ty, NavMesh.getCPtr(navmesh), navmesh);
    }

    public long buildNavMeshTile(long ref, NavMesh navmesh) {
        return RecastJNI.dtTileCache_buildNavMeshTile(swigCPtr, this, ref, NavMesh.getCPtr(navmesh), navmesh);
    }

    public void calcTightTileBounds(TileCacheLayerHeader header, SWIGTYPE_p_float bmin, SWIGTYPE_p_float bmax) {
        RecastJNI.dtTileCache_calcTightTileBounds(swigCPtr, this, TileCacheLayerHeader.getCPtr(header), header, SWIGTYPE_p_float.getCPtr(bmin), SWIGTYPE_p_float.getCPtr(bmax));
    }

    public void getObstacleBounds(TileCacheObstacle ob, SWIGTYPE_p_float bmin, SWIGTYPE_p_float bmax) {
        RecastJNI.dtTileCache_getObstacleBounds(swigCPtr, this, TileCacheObstacle.getCPtr(ob), ob, SWIGTYPE_p_float.getCPtr(bmin), SWIGTYPE_p_float.getCPtr(bmax));
    }

    public long encodeTileId(long salt, long it) {
        return RecastJNI.dtTileCache_encodeTileId(swigCPtr, this, salt, it);
    }

    public long decodeTileIdSalt(long ref) {
        return RecastJNI.dtTileCache_decodeTileIdSalt(swigCPtr, this, ref);
    }

    public long decodeTileIdTile(long ref) {
        return RecastJNI.dtTileCache_decodeTileIdTile(swigCPtr, this, ref);
    }

    public long encodeObstacleId(long salt, long it) {
        return RecastJNI.dtTileCache_encodeObstacleId(swigCPtr, this, salt, it);
    }

    public long decodeObstacleIdSalt(long ref) {
        return RecastJNI.dtTileCache_decodeObstacleIdSalt(swigCPtr, this, ref);
    }

    public long decodeObstacleIdObstacle(long ref) {
        return RecastJNI.dtTileCache_decodeObstacleIdObstacle(swigCPtr, this, ref);
    }
} public class TileCacheAlloc {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheAlloc() {
        this(RecastJNI.new_dtTileCacheAlloc(), true);
    }

    public TileCacheAlloc(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheAlloc obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheAlloc(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void reset() {
        RecastJNI.dtTileCacheAlloc_reset(swigCPtr, this);
    }

    public SWIGTYPE_p_void alloc(int size) {
        long cPtr = RecastJNI.dtTileCacheAlloc_alloc(swigCPtr, this, size);
        return (cPtr == 0) ? null : new SWIGTYPE_p_void(cPtr, false);
    }

    public void free(SWIGTYPE_p_void ptr) {
        RecastJNI.dtTileCacheAlloc_free(swigCPtr, this, SWIGTYPE_p_void.getCPtr(ptr));
    }
} public class TileCacheCompressor {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheCompressor(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheCompressor obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheCompressor(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public int maxCompressedSize(int bufferSize) {
        return RecastJNI.dtTileCacheCompressor_maxCompressedSize(swigCPtr, this, bufferSize);
    }

    public long compress(SWIGTYPE_p_unsigned_char buffer, int bufferSize, SWIGTYPE_p_unsigned_char compressed, int maxCompressedSize, SWIGTYPE_p_int compressedSize) {
        return RecastJNI.dtTileCacheCompressor_compress(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(buffer), bufferSize, SWIGTYPE_p_unsigned_char.getCPtr(compressed), maxCompressedSize, SWIGTYPE_p_int.getCPtr(compressedSize));
    }

    public long decompress(SWIGTYPE_p_unsigned_char compressed, int compressedSize, SWIGTYPE_p_unsigned_char buffer, int maxBufferSize, SWIGTYPE_p_int bufferSize) {
        return RecastJNI.dtTileCacheCompressor_decompress(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(compressed), compressedSize, SWIGTYPE_p_unsigned_char.getCPtr(buffer), maxBufferSize, SWIGTYPE_p_int.getCPtr(bufferSize));
    }
} public class TileCacheContour {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheContour() {
        this(RecastJNI.new_dtTileCacheContour(), true);
    }

    public TileCacheContour(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheContour obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheContour(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setNumberOfVertices(int value) {
        RecastJNI.dtTileCacheContour_nverts_set(swigCPtr, this, value);
    }

    public int getNumberOfVertices() {
        return RecastJNI.dtTileCacheContour_nverts_get(swigCPtr, this);
    }

    public void setVertices(char[] vertices) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(vertices);
        RecastJNI.dtTileCacheContour_verts_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getVertices() {
        long cPtr = RecastJNI.dtTileCacheContour_verts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getNumberOfVertices());
    }

    public void setRegionID(short value) {
        RecastJNI.dtTileCacheContour_reg_set(swigCPtr, this, value);
    }

    public short getRegionID() {
        return RecastJNI.dtTileCacheContour_reg_get(swigCPtr, this);
    }

    public void setArea(short value) {
        RecastJNI.dtTileCacheContour_area_set(swigCPtr, this, value);
    }

    public short getArea() {
        return RecastJNI.dtTileCacheContour_area_get(swigCPtr, this);
    }
} public class TileCacheContourSet {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheContourSet() {
        this(RecastJNI.new_dtTileCacheContourSet(), true);
    }

    public TileCacheContourSet(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheContourSet obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheContourSet(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setNumberOfContours(int value) {
        RecastJNI.dtTileCacheContourSet_nconts_set(swigCPtr, this, value);
    }

    public int getNumberOfContours() {
        return RecastJNI.dtTileCacheContourSet_nconts_get(swigCPtr, this);
    }

    public void setContours(TileCacheContour value) {
        RecastJNI.dtTileCacheContourSet_conts_set(swigCPtr, this, TileCacheContour.getCPtr(value), value);
    }

    public TileCacheContour getContours() {
        long cPtr = RecastJNI.dtTileCacheContourSet_conts_get(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheContour(cPtr, false);
    }
} public class TileCacheLayer {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheLayer() {
        this(RecastJNI.new_dtTileCacheLayer(), true);
    }

    public TileCacheLayer(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheLayer obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheLayer(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setHeader(TileCacheLayerHeader value) {
        RecastJNI.dtTileCacheLayer_header_set(swigCPtr, this, TileCacheLayerHeader.getCPtr(value), value);
    }

    public TileCacheLayerHeader getHeader() {
        long cPtr = RecastJNI.dtTileCacheLayer_header_get(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheLayerHeader(cPtr, false);
    }

    public void setRegionCount(short value) {
        RecastJNI.dtTileCacheLayer_regCount_set(swigCPtr, this, value);
    }

    public short getRegionCount() {
        return RecastJNI.dtTileCacheLayer_regCount_get(swigCPtr, this);
    }

    public void setHeights(char[] heights) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(heights);
        RecastJNI.dtTileCacheLayer_heights_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getHeights() {
        long cPtr = RecastJNI.dtTileCacheLayer_heights_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        //not sure if this is correct lenght of array
        return Converter.convertToChars(cPtr, getRegionCount());
    }

    public void setAreas(char[] areas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(areas);
        RecastJNI.dtTileCacheLayer_areas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getAreas() {
        long cPtr = RecastJNI.dtTileCacheLayer_areas_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        //not sure if this is correct lenght of array
        return Converter.convertToChars(cPtr, getRegionCount());
    }

    public void setConnections(char[] connections) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(connections);
        RecastJNI.dtTileCacheLayer_cons_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getConnections() {
        long cPtr = RecastJNI.dtTileCacheLayer_cons_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        //not sure if this is correct lenght of array
        return Converter.convertToChars(cPtr, getRegionCount());
    }

    public void setRegions(char[] regions) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(regions);
        RecastJNI.dtTileCacheLayer_regs_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    public char[] getRegions() {
        long cPtr = RecastJNI.dtTileCacheLayer_regs_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToChars(cPtr, getRegionCount());
    }
} public class TileCacheLayerHeader {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheLayerHeader() {
        this(RecastJNI.new_dtTileCacheLayerHeader(), true);
    }

    public TileCacheLayerHeader(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheLayerHeader obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheLayerHeader(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setMagic(int value) {
        RecastJNI.dtTileCacheLayerHeader_magic_set(swigCPtr, this, value);
    }

    public int getMagic() {
        return RecastJNI.dtTileCacheLayerHeader_magic_get(swigCPtr, this);
    }

    public void setVersion(int value) {
        RecastJNI.dtTileCacheLayerHeader_version_set(swigCPtr, this, value);
    }

    public int getVersion() {
        return RecastJNI.dtTileCacheLayerHeader_version_get(swigCPtr, this);
    }

    public void setTX(int value) {
        RecastJNI.dtTileCacheLayerHeader_tx_set(swigCPtr, this, value);
    }

    public int getTX() {
        return RecastJNI.dtTileCacheLayerHeader_tx_get(swigCPtr, this);
    }

    public void setTY(int value) {
        RecastJNI.dtTileCacheLayerHeader_ty_set(swigCPtr, this, value);
    }

    public int getTY() {
        return RecastJNI.dtTileCacheLayerHeader_ty_get(swigCPtr, this);
    }

    public void setTLayer(int value) {
        RecastJNI.dtTileCacheLayerHeader_tlayer_set(swigCPtr, this, value);
    }

    public int getTLayer() {
        return RecastJNI.dtTileCacheLayerHeader_tlayer_get(swigCPtr, this);
    }

    public void setMinBounds(Vector3f minBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(minBounds);
        RecastJNI.dtTileCacheLayerHeader_bmin_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public Vector3f getMinBounds() {
        long cPtr = RecastJNI.dtTileCacheLayerHeader_bmin_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    public void setMaxBounds(Vector3f maxBounds) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(maxBounds);
        RecastJNI.dtTileCacheLayerHeader_bmax_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));

    }

    public Vector3f getMaxBounds() {
        long cPtr = RecastJNI.dtTileCacheLayerHeader_bmax_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    public void setMinHeight(int value) {
        RecastJNI.dtTileCacheLayerHeader_hmin_set(swigCPtr, this, value);
    }

    public int getMinHeight() {
        return RecastJNI.dtTileCacheLayerHeader_hmin_get(swigCPtr, this);
    }

    public void setMaxHeight(int value) {
        RecastJNI.dtTileCacheLayerHeader_hmax_set(swigCPtr, this, value);
    }

    public int getMaxHeight() {
        return RecastJNI.dtTileCacheLayerHeader_hmax_get(swigCPtr, this);
    }

    public void setWidth(short value) {
        RecastJNI.dtTileCacheLayerHeader_width_set(swigCPtr, this, value);
    }

    public short getWidth() {
        return RecastJNI.dtTileCacheLayerHeader_width_get(swigCPtr, this);
    }

    public void setHeight(short value) {
        RecastJNI.dtTileCacheLayerHeader_height_set(swigCPtr, this, value);
    }

    public short getHeight() {
        return RecastJNI.dtTileCacheLayerHeader_height_get(swigCPtr, this);
    }

    public void setMinX(short value) {
        RecastJNI.dtTileCacheLayerHeader_minx_set(swigCPtr, this, value);
    }

    public short getMinX() {
        return RecastJNI.dtTileCacheLayerHeader_minx_get(swigCPtr, this);
    }

    public void setMaxX(short value) {
        RecastJNI.dtTileCacheLayerHeader_maxx_set(swigCPtr, this, value);
    }

    public short getMaxX() {
        return RecastJNI.dtTileCacheLayerHeader_maxx_get(swigCPtr, this);
    }

    public void setMinY(short value) {
        RecastJNI.dtTileCacheLayerHeader_miny_set(swigCPtr, this, value);
    }

    public short getMinY() {
        return RecastJNI.dtTileCacheLayerHeader_miny_get(swigCPtr, this);
    }

    public void setMaxY(short value) {
        RecastJNI.dtTileCacheLayerHeader_maxy_set(swigCPtr, this, value);
    }

    public short getMaxY() {
        return RecastJNI.dtTileCacheLayerHeader_maxy_get(swigCPtr, this);
    }
} public class TileCacheMeshProcess {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheMeshProcess(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheMeshProcess obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheMeshProcess(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    /**
     * WARNING: virtual
     *
     * @param params
     * @param polyAreas
     * @param polyFlags
     */
    public void process(NavMeshCreateParams params, SWIGTYPE_p_unsigned_char polyAreas, SWIGTYPE_p_unsigned_short polyFlags) {
        RecastJNI.dtTileCacheMeshProcess_process(swigCPtr, this, NavMeshCreateParams.getCPtr(params), params, SWIGTYPE_p_unsigned_char.getCPtr(polyAreas), SWIGTYPE_p_unsigned_short.getCPtr(polyFlags));
    }
} public class TileCacheObstacle {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheObstacle() {
        this(RecastJNI.new_dtTileCacheObstacle(), true);
    }

    public TileCacheObstacle(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheObstacle obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheObstacle(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setPosition(Vector3f position) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(position);
        RecastJNI.dtTileCacheObstacle_pos_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public Vector3f getPosition() {
        long cPtr = RecastJNI.dtTileCacheObstacle_pos_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToVector3f(cPtr);
    }

    public void setRadius(float value) {
        RecastJNI.dtTileCacheObstacle_radius_set(swigCPtr, this, value);
    }

    public float getRadius() {
        return RecastJNI.dtTileCacheObstacle_radius_get(swigCPtr, this);
    }

    public void setHeight(float value) {
        RecastJNI.dtTileCacheObstacle_height_set(swigCPtr, this, value);
    }

    public float getHeight() {
        return RecastJNI.dtTileCacheObstacle_height_get(swigCPtr, this);
    }

    public void setTouched(int[] touched) {
        SWIGTYPE_p_unsigned_int value = Converter.convertToSWIGTYPE_p_unsigned_int(touched);
        RecastJNI.dtTileCacheObstacle_touched_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    public int[] getTouched() {
        long cPtr = RecastJNI.dtTileCacheObstacle_touched_get(swigCPtr, this);
        if (cPtr == 0) return null; 
        return Converter.convertToInts(cPtr, getNumberOfTouched());
    }

    public void setPending(int[] pending) {
        SWIGTYPE_p_unsigned_int value = Converter.convertToSWIGTYPE_p_unsigned_int(pending);
        RecastJNI.dtTileCacheObstacle_pending_set(swigCPtr, this, SWIGTYPE_p_unsigned_int.getCPtr(value));
    }

    public int[] getPending() {
        long cPtr = RecastJNI.dtTileCacheObstacle_pending_get(swigCPtr, this);
        if (cPtr == 0) return null;
        return Converter.convertToInts(cPtr, getNumberOfPending());
    }

    public void setSalt(int value) {
        RecastJNI.dtTileCacheObstacle_salt_set(swigCPtr, this, value);
    }

    public int getSalt() {
        return RecastJNI.dtTileCacheObstacle_salt_get(swigCPtr, this);
    }

    public void setState(short value) {
        RecastJNI.dtTileCacheObstacle_state_set(swigCPtr, this, value);
    }

    public short getState() {
        return RecastJNI.dtTileCacheObstacle_state_get(swigCPtr, this);
    }

    public void setNumberOfTouched(short value) {
        RecastJNI.dtTileCacheObstacle_ntouched_set(swigCPtr, this, value);
    }

    public short getNumberOfTouched() {
        return RecastJNI.dtTileCacheObstacle_ntouched_get(swigCPtr, this);
    }

    public void setNumberOfPending(short value) {
        RecastJNI.dtTileCacheObstacle_npending_set(swigCPtr, this, value);
    }

    public short getNumberOfPending() {
        return RecastJNI.dtTileCacheObstacle_npending_get(swigCPtr, this);
    }

    public void setNext(TileCacheObstacle value) {
        RecastJNI.dtTileCacheObstacle_next_set(swigCPtr, this, TileCacheObstacle.getCPtr(value), value);
    }

    public TileCacheObstacle getNext() {
        long cPtr = RecastJNI.dtTileCacheObstacle_next_get(swigCPtr, this);
        return (cPtr == 0) ? null : new TileCacheObstacle(cPtr, false);
    }
} public class TileCacheParams {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCacheParams() {
        this(RecastJNI.new_dtTileCacheParams(), true);
    }

    public TileCacheParams(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCacheParams obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCacheParams(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setOrigin(Vector3f position) {
        SWIGTYPE_p_float value = Converter.convertToSWIGTYPE_p_float(position);
        RecastJNI.dtTileCacheParams_orig_set(swigCPtr, this, SWIGTYPE_p_float.getCPtr(value));
    }

    public Vector3f getOrigin() {
        long cPtr = RecastJNI.dtTileCacheParams_orig_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToVector3f(cPtr);
    }

    public void setCellSize(float value) {
        RecastJNI.dtTileCacheParams_cs_set(swigCPtr, this, value);
    }

    public float getCellSize() {
        return RecastJNI.dtTileCacheParams_cs_get(swigCPtr, this);
    }

    public void setCellHeight(float value) {
        RecastJNI.dtTileCacheParams_ch_set(swigCPtr, this, value);
    }

    public float getCellHeight() {
        return RecastJNI.dtTileCacheParams_ch_get(swigCPtr, this);
    }

    public void setWidth(int value) {
        RecastJNI.dtTileCacheParams_width_set(swigCPtr, this, value);
    }

    public int getWidth() {
        return RecastJNI.dtTileCacheParams_width_get(swigCPtr, this);
    }

    public void setHeight(int value) {
        RecastJNI.dtTileCacheParams_height_set(swigCPtr, this, value);
    }

    public int getHeight() {
        return RecastJNI.dtTileCacheParams_height_get(swigCPtr, this);
    }

    public void setWalkableHeight(float value) {
        RecastJNI.dtTileCacheParams_walkableHeight_set(swigCPtr, this, value);
    }

    public float getWalkableHeight() {
        return RecastJNI.dtTileCacheParams_walkableHeight_get(swigCPtr, this);
    }

    public void setWalkableRadius(float value) {
        RecastJNI.dtTileCacheParams_walkableRadius_set(swigCPtr, this, value);
    }

    public float getWalkableRadius() {
        return RecastJNI.dtTileCacheParams_walkableRadius_get(swigCPtr, this);
    }

    public void setWalkableClimb(float value) {
        RecastJNI.dtTileCacheParams_walkableClimb_set(swigCPtr, this, value);
    }

    public float getWalkableClimb() {
        return RecastJNI.dtTileCacheParams_walkableClimb_get(swigCPtr, this);
    }

    public void setMaxSimplificationError(float value) {
        RecastJNI.dtTileCacheParams_maxSimplificationError_set(swigCPtr, this, value);
    }

    public float getMaxSimplificationError() {
        return RecastJNI.dtTileCacheParams_maxSimplificationError_get(swigCPtr, this);
    }

    public void setMaxTiles(int value) {
        RecastJNI.dtTileCacheParams_maxTiles_set(swigCPtr, this, value);
    }

    public int getMaxTiles() {
        return RecastJNI.dtTileCacheParams_maxTiles_get(swigCPtr, this);
    }

    public void setMaxObstacles(int value) {
        RecastJNI.dtTileCacheParams_maxObstacles_set(swigCPtr, this, value);
    }

    public int getMaxObstacles() {
        return RecastJNI.dtTileCacheParams_maxObstacles_get(swigCPtr, this);
    }
} public class TileCachePolyMesh {

    private long swigCPtr;
    protected boolean swigCMemOwn;

    public TileCachePolyMesh() {
        this(RecastJNI.new_dtTileCachePolyMesh(), true);
    }

    public TileCachePolyMesh(long cPtr, boolean cMemoryOwn) {
        swigCMemOwn = cMemoryOwn;
        swigCPtr = cPtr;
    }

    public static long getCPtr(TileCachePolyMesh obj) {
        return (obj == null) ? 0 : obj.swigCPtr;
    }

    @Override
    protected void finalize() {
        delete();
    }

    public synchronized void delete() {
        if (swigCPtr != 0) {
            if (swigCMemOwn) {
                swigCMemOwn = false;
                RecastJNI.delete_dtTileCachePolyMesh(swigCPtr);
            }
            swigCPtr = 0;
        }
    }

    public void setNumberOfVerticesPerPolygons(int value) {
        RecastJNI.dtTileCachePolyMesh_nvp_set(swigCPtr, this, value);
    }

    public int getNumberOfVerticesPerPolygons() {
        return RecastJNI.dtTileCachePolyMesh_nvp_get(swigCPtr, this);
    }

    /**
     *
     * @param value Number of vertices.
     */
    public void setNumberOfVertices(int value) {
        RecastJNI.dtTileCachePolyMesh_nverts_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Number of vertices.
     */
    public int getNumberOfVertices() {
        return RecastJNI.dtTileCachePolyMesh_nverts_get(swigCPtr, this);
    }

    /**
     *
     * @param value Number of polygons.
     */
    public void setNumberOfPolygons(int value) {
        RecastJNI.dtTileCachePolyMesh_npolys_set(swigCPtr, this, value);
    }

    /**
     *
     * @return Number of polygons.
     */
    public int getNumberOfPolygons() {
        return RecastJNI.dtTileCachePolyMesh_npolys_get(swigCPtr, this);
    }

    /**
     *
     * @param vertices Vertices of the mesh, 3 elements per vertex.
     */
    public void setVertices(short[] vertices) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(vertices);
        RecastJNI.dtTileCachePolyMesh_verts_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Vertices of the mesh, 3 elements per vertex.
     */
    public short[] getVertices() {
        long cPtr = RecastJNI.dtTileCachePolyMesh_verts_get(swigCPtr, this);
        if (cPtr == 0) {
            return null;
        }
        return Converter.convertToShorts(cPtr, getNumberOfVertices());
    }

    /**
     *
     * @param polygons Polygons of the mesh, nvp*2 elements per polygon.
     */
    public void setPolygons(short[] polygons) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(polygons);
        RecastJNI.dtTileCachePolyMesh_polys_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Polygons of the mesh, nvp*2 elements per polygon.
     */
    public short[] getPolygons() {
        long cPtr = RecastJNI.dtTileCachePolyMesh_polys_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getNumberOfPolygons());
    }

    /**
     *
     * @param flags Per polygon flags.
     */
    public void setFlags(short[] flags) {
        SWIGTYPE_p_unsigned_short value = Converter.convertToSWIGTYPE_p_unsigned_short(flags);
        RecastJNI.dtTileCachePolyMesh_flags_set(swigCPtr, this, SWIGTYPE_p_unsigned_short.getCPtr(value));
    }

    /**
     *
     * @return Per polygon flags.
     */
    public short[] getFlags() {
        long cPtr = RecastJNI.dtTileCachePolyMesh_flags_get(swigCPtr, this);
        //check count
        return (cPtr == 0) ? null : Converter.convertToShorts(cPtr, getNumberOfPolygons());
    }

    /**
     *
     * @param areas Area ID of polygons.
     */
    public void setAreas(char[] areas) {
        SWIGTYPE_p_unsigned_char value = Converter.convertToSWIGTYPE_p_unsigned_char(areas);
        RecastJNI.dtTileCachePolyMesh_areas_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
    }

    /**
     *
     * @return Area ID of polygons.
     */
    public char[] getAreas() {
        long cPtr = RecastJNI.dtTileCachePolyMesh_areas_get(swigCPtr, this);
        return (cPtr == 0) ? null : Converter.convertToChars(cPtr, getNumberOfPolygons());
    }
}
import com.jme3.ai.navigation.crowd.dtCrowd;
import com.jme3.ai.navigation.crowd.dtCrowdAgent;
import com.jme3.ai.navigation.crowd.dtCrowdAgentAnimation;
import com.jme3.ai.navigation.crowd.dtCrowdAgentDebugInfo;
import com.jme3.ai.navigation.crowd.dtCrowdAgentParams;
import com.jme3.ai.navigation.crowd.dtCrowdNeighbour;
import com.jme3.ai.navigation.crowd.dtLocalBoundary;
import com.jme3.ai.navigation.crowd.dtObstacleAvoidanceDebugData;
import com.jme3.ai.navigation.crowd.dtObstacleAvoidanceParams;
import com.jme3.ai.navigation.crowd.dtObstacleAvoidanceQuery;
import com.jme3.ai.navigation.crowd.dtObstacleCircle;
import com.jme3.ai.navigation.crowd.dtObstacleSegment;
import com.jme3.ai.navigation.crowd.dtPathQueue;
import com.jme3.ai.navigation.crowd.dtProximityGrid;
import com.jme3.ai.navigation.detour.BVNode;
import com.jme3.ai.navigation.detour.Link;
import com.jme3.ai.navigation.detour.MeshHeader;
import com.jme3.ai.navigation.detour.MeshTile;
import com.jme3.ai.navigation.detour.NavMesh;
import com.jme3.ai.navigation.detour.NavMeshCreateParams;
import com.jme3.ai.navigation.detour.NavMeshParams;
import com.jme3.ai.navigation.detour.NavMeshQuery;
import com.jme3.ai.navigation.detour.Node;
import com.jme3.ai.navigation.detour.NodePool;
import com.jme3.ai.navigation.detour.NodeQueue;
import com.jme3.ai.navigation.detour.OffMeshConnection;
import com.jme3.ai.navigation.detour.PathCorridor;
import com.jme3.ai.navigation.detour.Poly;
import com.jme3.ai.navigation.detour.PolyDetail;
import com.jme3.ai.navigation.detour.QueryFilter;
import com.jme3.ai.navigation.recast.CompactCell;
import com.jme3.ai.navigation.recast.CompactHeightfield;
import com.jme3.ai.navigation.recast.CompactSpan;
import com.jme3.ai.navigation.recast.Config;
import com.jme3.ai.navigation.recast.Context;
import com.jme3.ai.navigation.recast.Contour;
import com.jme3.ai.navigation.recast.ContourSet;
import com.jme3.ai.navigation.recast.Heightfield;
import com.jme3.ai.navigation.recast.HeightfieldLayer;
import com.jme3.ai.navigation.recast.HeightfieldLayerSet;
import com.jme3.ai.navigation.recast.PolyMesh;
import com.jme3.ai.navigation.recast.PolyMeshDetail;
import com.jme3.ai.navigation.recast.Span;
import com.jme3.ai.navigation.tilecache.CompressedTile;
import com.jme3.ai.navigation.tilecache.TileCache;
import com.jme3.ai.navigation.tilecache.TileCacheAlloc;
import com.jme3.ai.navigation.tilecache.TileCacheCompressor;
import com.jme3.ai.navigation.tilecache.TileCacheContour;
import com.jme3.ai.navigation.tilecache.TileCacheContourSet;
import com.jme3.ai.navigation.tilecache.TileCacheLayer;
import com.jme3.ai.navigation.tilecache.TileCacheLayerHeader;
import com.jme3.ai.navigation.tilecache.TileCacheMeshProcess;
import com.jme3.ai.navigation.tilecache.TileCacheObstacle;
import com.jme3.ai.navigation.tilecache.TileCacheParams;
import com.jme3.ai.navigation.tilecache.TileCachePolyMesh;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
package com.jme3.ai.navigation.utils;


public class RecastJNI {

    public static native long new_DoubleArray(int jarg1);

    public static native void delete_DoubleArray(long jarg1);

    public static native double DoubleArray_getitem(long jarg1, DoubleArray jarg1_, int jarg2);

    public static native void DoubleArray_setitem(long jarg1, DoubleArray jarg1_, int jarg2, double jarg3);

    public static native long DoubleArray_cast(long jarg1, DoubleArray jarg1_);

    public static native long DoubleArray_frompointer(long jarg1);

    public static native long new_FloatArray(int jarg1);

    public static native void delete_FloatArray(long jarg1);

    public static native float FloatArray_getitem(long jarg1, FloatArray jarg1_, int jarg2);

    public static native void FloatArray_setitem(long jarg1, FloatArray jarg1_, int jarg2, float jarg3);

    public static native long FloatArray_cast(long jarg1, FloatArray jarg1_);

    public static native long FloatArray_frompointer(long jarg1);

    public static native long new_IntArray(int jarg1);

    public static native void delete_IntArray(long jarg1);

    public static native int IntArray_getitem(long jarg1, IntArray jarg1_, int jarg2);

    public static native void IntArray_setitem(long jarg1, IntArray jarg1_, int jarg2, int jarg3);

    public static native long IntArray_cast(long jarg1, IntArray jarg1_);

    public static native long IntArray_frompointer(long jarg1);

    public static native long new_UCharArray(int jarg1);

    public static native void delete_UCharArray(long jarg1);

    public static native short UCharArray_getitem(long jarg1, UCharArray jarg1_, int jarg2);

    public static native void UCharArray_setitem(long jarg1, UCharArray jarg1_, int jarg2, short jarg3);

    public static native long UCharArray_cast(long jarg1, UCharArray jarg1_);

    public static native long UCharArray_frompointer(long jarg1);

    public static native long new_UShortArray(int jarg1);

    public static native void delete_UShortArray(long jarg1);

    public static native int UShortArray_getitem(long jarg1, UShortArray jarg1_, int jarg2);

    public static native void UShortArray_setitem(long jarg1, UShortArray jarg1_, int jarg2, int jarg3);

    public static native long UShortArray_cast(long jarg1, UShortArray jarg1_);

    public static native long UShortArray_frompointer(long jarg1);

    public static native long new_UIntArray(int jarg1);

    public static native void delete_UIntArray(long jarg1);

    public static native long UIntArray_getitem(long jarg1, UIntArray jarg1_, int jarg2);

    public static native void UIntArray_setitem(long jarg1, UIntArray jarg1_, int jarg2, long jarg3);

    public static native long UIntArray_cast(long jarg1, UIntArray jarg1_);

    public static native long UIntArray_frompointer(long jarg1);

    public static native long new_LongArray(int jarg1);

    public static native void delete_LongArray(long jarg1);

    public static native int LongArray_getitem(long jarg1, LongArray jarg1_, int jarg2);

    public static native void LongArray_setitem(long jarg1, LongArray jarg1_, int jarg2, int jarg3);

    public static native long LongArray_cast(long jarg1, LongArray jarg1_);

    public static native long LongArray_frompointer(long jarg1);

    public static native long new_BooleanArray(int jarg1);

    public static native void delete_BooleanArray(long jarg1);

    public static native boolean BooleanArray_getitem(long jarg1, BooleanArray jarg1_, int jarg2);

    public static native void BooleanArray_setitem(long jarg1, BooleanArray jarg1_, int jarg2, boolean jarg3);

    public static native long BooleanArray_cast(long jarg1, BooleanArray jarg1_);

    public static native long BooleanArray_frompointer(long jarg1);

    public static native void dtAllocSetCustom(long jarg1, long jarg2);

    public static native long dtAlloc(int jarg1, int jarg2);

    public static native void dtFree(long jarg1);

    public static native float dtSqrt(float jarg1);

    public static native void dtVcross(long jarg1, long jarg2, long jarg3);

    public static native float dtVdot(long jarg1, long jarg2);

    public static native void dtVmad(long jarg1, long jarg2, long jarg3, float jarg4);

    public static native void dtVlerp(long jarg1, long jarg2, long jarg3, float jarg4);

    public static native void dtVadd(long jarg1, long jarg2, long jarg3);

    public static native void dtVsub(long jarg1, long jarg2, long jarg3);

    public static native void dtVscale(long jarg1, long jarg2, float jarg3);

    public static native void dtVmin(long jarg1, long jarg2);

    public static native void dtVmax(long jarg1, long jarg2);

    public static native void dtVset(long jarg1, float jarg2, float jarg3, float jarg4);

    public static native void dtVcopy(long jarg1, long jarg2);

    public static native float dtVlen(long jarg1);

    public static native float dtVlenSqr(long jarg1);

    public static native float dtVdist(long jarg1, long jarg2);

    public static native float dtVdistSqr(long jarg1, long jarg2);

    public static native float dtVdist2D(long jarg1, long jarg2);

    public static native float dtVdist2DSqr(long jarg1, long jarg2);

    public static native void dtVnormalize(long jarg1);

    public static native boolean dtVequal(long jarg1, long jarg2);

    public static native float dtVdot2D(long jarg1, long jarg2);

    public static native float dtVperp2D(long jarg1, long jarg2);

    public static native float dtTriArea2D(long jarg1, long jarg2, long jarg3);

    public static native boolean dtOverlapQuantBounds(long jarg1, long jarg2, long jarg3, long jarg4);

    public static native boolean dtOverlapBounds(long jarg1, long jarg2, long jarg3, long jarg4);

    public static native void dtClosestPtPointTriangle(long jarg1, long jarg2, long jarg3, long jarg4, long jarg5);

    public static native boolean dtClosestHeightPointTriangle(long jarg1, long jarg2, long jarg3, long jarg4, long jarg5);

    public static native boolean dtIntersectSegmentPoly2D(long jarg1, long jarg2, long jarg3, int jarg4, long jarg5, long jarg6, long jarg7, long jarg8);

    public static native boolean dtIntersectSegSeg2D(long jarg1, long jarg2, long jarg3, long jarg4, long jarg5, long jarg6);

    public static native boolean dtPointInPolygon(long jarg1, long jarg2, int jarg3);

    public static native boolean dtDistancePtPolyEdgesSqr(long jarg1, long jarg2, int jarg3, long jarg4, long jarg5);

    public static native float dtDistancePtSegSqr2D(long jarg1, long jarg2, long jarg3, long jarg4);

    public static native void dtCalcPolyCenter(long jarg1, long jarg2, int jarg3, long jarg4);

    public static native boolean dtOverlapPolyPoly2D(long jarg1, int jarg2, long jarg3, int jarg4);

    public static native long dtNextPow2(long jarg1);

    public static native long dtIlog2(long jarg1);

    public static native int dtAlign4(int jarg1);

    public static native int dtOppositeTile(int jarg1);

    public static native void dtSwapByte(long jarg1, long jarg2);

    public static native void dtSwapEndian__SWIG_0(long jarg1);

    public static native void dtSwapEndian__SWIG_1(long jarg1);

    public static native void dtSwapEndian__SWIG_2(long jarg1);

    public static native void dtSwapEndian__SWIG_3(long jarg1);

    public static native void dtSwapEndian__SWIG_4(long jarg1);

    public static native void dtRandomPointInConvexPoly(long jarg1, int jarg2, long jarg3, float jarg4, float jarg5, long jarg6);

    public static native int DT_CROWDAGENT_MAX_NEIGHBOURS_get();

    public static native int DT_CROWDAGENT_MAX_CORNERS_get();

    public static native int DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS_get();

    public static native int DT_CROWD_MAX_QUERY_FILTER_TYPE_get();

    public static native void dtCrowdNeighbour_idx_set(long jarg1, dtCrowdNeighbour jarg1_, int jarg2);