示例#1
0
void Actor::setActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint) {
	Point nextPoint;
	int8 direction;

	_pathList[0] = toPoint;
	nextPoint = toPoint;

	_pathListIndex = 0;
	while (!(nextPoint == fromPoint)) {
		direction = getPathCell(nextPoint);
		if ((direction < 0) || (direction >= 8)) {
			error("Actor::setActorPath error direction 0x%X", direction);
		}
		nextPoint.x -= pathDirectionLUT2[direction][0];
		nextPoint.y -= pathDirectionLUT2[direction][1];
		++_pathListIndex;
		if (_pathListIndex >= _pathList.size()) {
			_pathList.push_back(nextPoint);
		} else {
			_pathList[_pathListIndex] = nextPoint;
		}

#ifdef ACTOR_DEBUG
		addDebugPoint(nextPoint, 0x8a);
#endif
	}

	pathToNode();
	removeNodes();
	nodeToPath();
	removePathPoints();

	for (uint i = 0; i < _pathNodeList.size(); i++) {
		actor->addWalkStepPoint(_pathNodeList[i].point);
	}
}
示例#2
0
void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint) {
	Point iteratorPoint;
	Point bestPoint;
	int maskType;
	int i;
	Rect intersect;

#ifdef ACTOR_DEBUG
	_debugPointsCount = 0;
#endif

	actor->_walkStepsCount = 0;
	if (fromPoint == toPoint) {
		actor->addWalkStepPoint(toPoint);
		return;
	}

	for (iteratorPoint.y = 0; iteratorPoint.y < _yCellCount; iteratorPoint.y++) {
		for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) {
			if (_vm->_scene->validBGMaskPoint(iteratorPoint)) {
				maskType = _vm->_scene->getBGMaskType(iteratorPoint);
				setPathCell(iteratorPoint, _vm->_scene->getDoorState(maskType) ? kPathCellBarrier : kPathCellEmpty);
			} else {
				setPathCell(iteratorPoint, kPathCellBarrier);
			}
		}
	}

	for (i = 0; i < _barrierCount; i++) {
		intersect.left = MAX(_pathRect.left, _barrierList[i].left);
		intersect.top = MAX(_pathRect.top, _barrierList[i].top);
		intersect.right = MIN(_pathRect.right, _barrierList[i].right);
		intersect.bottom = MIN(_pathRect.bottom, _barrierList[i].bottom);

		for (iteratorPoint.y = intersect.top; iteratorPoint.y < intersect.bottom; iteratorPoint.y++) {
			for (iteratorPoint.x = intersect.left; iteratorPoint.x < intersect.right; iteratorPoint.x++) {
				setPathCell(iteratorPoint, kPathCellBarrier);
			}
		}
	}

#ifdef ACTOR_DEBUG
	for (iteratorPoint.y = 0; iteratorPoint.y < _yCellCount; iteratorPoint.y++) {
		for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) {
			if (getPathCell(iteratorPoint) == kPathCellBarrier) {
				addDebugPoint(iteratorPoint, 24);
			}
		}
	}
#endif

	if (scanPathLine(fromPoint, toPoint)) {
		actor->addWalkStepPoint(fromPoint);
		actor->addWalkStepPoint(toPoint);
		return;
	}

	i = fillPathArray(fromPoint, toPoint, bestPoint);

	if (fromPoint == bestPoint) {
		actor->addWalkStepPoint(bestPoint);
		return;
	}

	if (i == 0) {
		error("fillPathArray returns zero");
	}

	setActorPath(actor, fromPoint, bestPoint);
}
示例#3
0
int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint) {
	int bestRating;
	int currentRating;
	Point bestPath;
	int pointCounter;
	const PathDirectionData *samplePathDirection;
	Point nextPoint;
	int directionCount;
	int16 compressX = (_vm->getGameId() == GID_ITE) ? 2 : 1;

	Common::List<PathDirectionData> pathDirectionQueue;

	pointCounter = 0;
	bestRating = quickDistance(fromPoint, toPoint, compressX);
	bestPath = fromPoint;

	for (int8 startDirection = 0; startDirection < 4; startDirection++) {
		PathDirectionData tmp = { startDirection, fromPoint.x, fromPoint.y };
		pathDirectionQueue.push_back(tmp);
	}

	if (validPathCellPoint(fromPoint)) {
		setPathCell(fromPoint, kDirUp);

#ifdef ACTOR_DEBUG
		addDebugPoint(fromPoint, 24+36);
#endif
	}

	while (!pathDirectionQueue.empty()) {
		PathDirectionData curPathDirection = pathDirectionQueue.front();
		pathDirectionQueue.pop_front();
		for (directionCount = 0; directionCount < 3; directionCount++) {
			samplePathDirection = &pathDirectionLUT[curPathDirection.direction][directionCount];
			nextPoint = Point(curPathDirection.x, curPathDirection.y);
			nextPoint.x += samplePathDirection->x;
			nextPoint.y += samplePathDirection->y;

			if (!validPathCellPoint(nextPoint)) {
				continue;
			}

			if (getPathCell(nextPoint) != kPathCellEmpty) {
				continue;
			}

			setPathCell(nextPoint, samplePathDirection->direction);

#ifdef ACTOR_DEBUG
			addDebugPoint(nextPoint, samplePathDirection->direction + 96);
#endif
			PathDirectionData tmp = {
				samplePathDirection->direction,
				nextPoint.x, nextPoint.y };
			pathDirectionQueue.push_back(tmp);
			++pointCounter;
			if (nextPoint == toPoint) {
				bestPoint = toPoint;
				return pointCounter;
			}
			currentRating = quickDistance(nextPoint, toPoint, compressX);
			if (currentRating < bestRating) {
				bestRating = currentRating;
				bestPath = nextPoint;
			}
		}
	}

	bestPoint = bestPath;
	return pointCounter;
}
示例#4
0
文件: AABB.cpp 项目: mrG7/Hullinator
bool AABB::intersectsTri( const PrecomputedTriangle& tri, Vector3f &penetration ) const
{
  // the algorith on pg 168 of rtcd is:
  // do SAT test on:
  // 1. tri normal
  // 2. 3 face normals from aabb
  // 3. 9 axes given by cross products of COMBINATIONS OF EDGES from both the tri and aabb.
  //   - The aabb has 3 unique edge directions (principle axes), and the tri has 3 unique edges.
  
  float minOverlap = HUGE ;
  Vector3f axisOfMinOverlap ; // value b/c the crossed axes are temporary
  
  
  // 1. tri normal
  float meMin, meMax, oMin, oMax, lowerLim, upperLim ;
  SATtest( tri.plane.normal, corners, meMin, meMax ) ;
  SATtest( tri.plane.normal, tri.a, oMin, oMax ) ; //Only need to test 1 pt from tri, since all 3 will collapse to same pt.
  
  // Because the tri is going to appear as a POINT in the test, 
  // we have to use `maxOverlaps`.  See the comments in `maxOverlaps`
  // for how it detects overlaps differently than plain `overlaps`
  if( !maxOverlaps( meMin, meMax, oMin, oMax, lowerLim, upperLim ) ) {
    addDebugLine( tri.plane.normal*meMin, tri.plane.normal*meMax, Red ) ;
    addDebugPoint( tri.plane.normal*oMin, Blue ) ;
    return 0 ;
  }
  
  // These by default are the maxes then
  minOverlap = upperLim-lowerLim ;
  axisOfMinOverlap = tri.plane.normal ;
  
  // 2. 3 face normals from aabb.
  for( int axis = 0 ; axis < 3 ; axis++ )
  {
    // because we're projecting points in 3 space TO THE PRINCIPAL AXES,
    // the span of the projection of all the vertices is just going to be
    // the min/max in each priniciple axis direction.
    // Does this look like I ripped this off the convex hull intersection code, cuz i did.
    meMin=HUGE,meMax=-HUGE ; // init these here
    for( int j = 0 ; j < corners.size() ; j++ )
    {
      if( corners[j].elts[axis] < meMin )  meMin=corners[j].elts[axis];
      if( corners[j].elts[axis] > meMax )  meMax=corners[j].elts[axis];
    }
    
    // we "cheat" here and just pick out the correct index for the aabb.
    // its axis aligned!
    oMin=min.elts[axis] ;
    oMax=max.elts[axis] ;
    if( !overlaps( meMin, meMax, oMin, oMax, lowerLim, upperLim ) )
      return 0 ;
    
    // Overlaps.  See if this was the smallest overlap yet  
    float overlap=upperLim-lowerLim ;
    if( overlap < minOverlap ) {
      axisOfMinOverlap = axis ;
      minOverlap = overlap ;
    }
  }
  
  // See how inaccurate it is w/o cross products
  //penetration = axisOfMinOverlap*minOverlap ;
  //return 1 ;
  // 3 cross products.
  for( int aabbAxis = 0 ; aabbAxis < 3 ; aabbAxis++ )
  {
    for( int triEdge=0 ; triEdge < 3 ; triEdge++ )
    {
      Vector3f axis = SATAxes[aabbAxis].cross( tri.edges[triEdge] ) ;
      if( axis.allzero() ) skip ; // this happens often
      axis.normalize() ;
      
      SATtest( axis, corners, meMin, meMax ) ;
      SATtest( axis, &tri.a, 3, oMin, oMax ) ; // use all 3 tri verts.
      
      if( !overlaps( meMin, meMax, oMin, oMax, lowerLim, upperLim ) ) {
        //addDebugLine( transformedNormals[i]*meMin, transformedNormals[i]*meMax, Red ) ;
        //addDebugLine( transformedNormals[i]*oMin, transformedNormals[i]*oMax, Blue ) ;
        return 0 ;
      }
      
      // Overlaps.  See if this was the smallest overlap yet  
      float overlap=upperLim-lowerLim ;
      if( overlap < minOverlap ) {
        axisOfMinOverlap = axis ;
        minOverlap = overlap ;
      }
    }
  }
  
  penetration = axisOfMinOverlap*minOverlap ;
  return 1 ;
}