mirror of https://github.com/axmolengine/axmol.git
fixed bug #21800 [CppTest]Node: Scene3D when player outof terrain app will no response.
This commit is contained in:
parent
cb751e3c1a
commit
354f64ec51
|
@ -29,6 +29,11 @@ Ray::Ray()
|
|||
{
|
||||
}
|
||||
|
||||
Ray::Ray(const Ray& ray)
|
||||
{
|
||||
set(ray._origin, ray._direction);
|
||||
}
|
||||
|
||||
Ray::Ray(const Vec3& origin, const Vec3& direction)
|
||||
{
|
||||
set(origin, direction);
|
||||
|
|
|
@ -541,8 +541,12 @@ cocos2d::Vec3 Terrain::getIntersectionPoint(const Ray & ray) const
|
|||
}
|
||||
}
|
||||
|
||||
bool Terrain::getIntersectionPoint(const Ray & ray, Vec3 & intersectionPoint) const
|
||||
bool Terrain::getIntersectionPoint(const Ray & ray_, Vec3 & intersectionPoint) const
|
||||
{
|
||||
// convert ray from world space to local space
|
||||
Ray ray(ray_);
|
||||
getWorldToNodeTransform().transformPoint(&(ray._origin));
|
||||
|
||||
std::set<Chunk *> closeList;
|
||||
Vec2 start = Vec2(ray._origin.x,ray._origin.z);
|
||||
Vec2 dir = Vec2(ray._direction.x,ray._direction.z);
|
||||
|
|
|
@ -869,53 +869,28 @@ void Scene3DTestScene::onTouchEnd(Touch* touch, Event* event)
|
|||
if(_player)
|
||||
{
|
||||
Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
|
||||
// first, convert screen touch location to the world location on near and far plane
|
||||
// convert screen touch location to the world location on near and far plane
|
||||
auto size = Director::getInstance()->getWinSize();
|
||||
camera->unprojectGL(size, &nearP, &nearP);
|
||||
camera->unprojectGL(size, &farP, &farP);
|
||||
// second, convert world location to terrain's local position on near/far plane
|
||||
auto worldToNodeMat = _terrain->getNodeToWorldTransform();
|
||||
worldToNodeMat.inverse();
|
||||
worldToNodeMat.transformPoint(&nearP);
|
||||
worldToNodeMat.transformPoint(&farP);
|
||||
// create a ray from point which on near plane to point which on far plane
|
||||
Vec3 dir = farP - nearP;
|
||||
dir.normalize();
|
||||
Vec3 rayStep = 15*dir;
|
||||
Vec3 rayPos = nearP;
|
||||
Vec3 rayStartPosition = nearP;
|
||||
Vec3 lastRayPosition =rayPos;
|
||||
rayPos += rayStep;
|
||||
// Linear search - Loop until find a point inside and outside the terrain Vector3
|
||||
float height = _terrain->getHeight(rayPos.x,rayPos.z);
|
||||
|
||||
while (rayPos.y > height)
|
||||
Vec3 collisionPoint;
|
||||
bool isInTerrain = _terrain->getIntersectionPoint(Ray(nearP, dir), collisionPoint);
|
||||
if (!isInTerrain)
|
||||
{
|
||||
lastRayPosition = rayPos;
|
||||
rayPos += rayStep;
|
||||
height = _terrain->getHeight(rayPos.x,rayPos.z);
|
||||
_player->idle();
|
||||
}
|
||||
|
||||
Vec3 startPosition = lastRayPosition;
|
||||
Vec3 endPosition = rayPos;
|
||||
|
||||
for (int i= 0; i< 32; i++)
|
||||
else
|
||||
{
|
||||
// Binary search pass
|
||||
Vec3 middlePoint = (startPosition + endPosition) * 0.5f;
|
||||
if (middlePoint.y < height)
|
||||
endPosition = middlePoint;
|
||||
else
|
||||
startPosition = middlePoint;
|
||||
dir = collisionPoint - _player->getPosition3D();
|
||||
dir.y = 0;
|
||||
dir.normalize();
|
||||
_player->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
|
||||
dir.cross(dir,Vec3(0,0,-1),&_player->_headingAxis);
|
||||
_player->_targetPos=collisionPoint;
|
||||
_player->forward();
|
||||
}
|
||||
Vec3 collisionPoint = (startPosition + endPosition) * 0.5f;
|
||||
dir = collisionPoint - _player->getPosition3D();
|
||||
dir.y = 0;
|
||||
dir.normalize();
|
||||
_player->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
|
||||
dir.cross(dir,Vec3(0,0,-1),&_player->_headingAxis);
|
||||
_player->_targetPos=collisionPoint;
|
||||
_player->forward();
|
||||
}
|
||||
event->stopPropagation();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue