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)
|
Ray::Ray(const Vec3& origin, const Vec3& direction)
|
||||||
{
|
{
|
||||||
set(origin, 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;
|
std::set<Chunk *> closeList;
|
||||||
Vec2 start = Vec2(ray._origin.x,ray._origin.z);
|
Vec2 start = Vec2(ray._origin.x,ray._origin.z);
|
||||||
Vec2 dir = Vec2(ray._direction.x,ray._direction.z);
|
Vec2 dir = Vec2(ray._direction.x,ray._direction.z);
|
||||||
|
|
|
@ -869,53 +869,28 @@ void Scene3DTestScene::onTouchEnd(Touch* touch, Event* event)
|
||||||
if(_player)
|
if(_player)
|
||||||
{
|
{
|
||||||
Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
|
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();
|
auto size = Director::getInstance()->getWinSize();
|
||||||
camera->unprojectGL(size, &nearP, &nearP);
|
camera->unprojectGL(size, &nearP, &nearP);
|
||||||
camera->unprojectGL(size, &farP, &farP);
|
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;
|
Vec3 dir = farP - nearP;
|
||||||
dir.normalize();
|
dir.normalize();
|
||||||
Vec3 rayStep = 15*dir;
|
Vec3 collisionPoint;
|
||||||
Vec3 rayPos = nearP;
|
bool isInTerrain = _terrain->getIntersectionPoint(Ray(nearP, dir), collisionPoint);
|
||||||
Vec3 rayStartPosition = nearP;
|
if (!isInTerrain)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
lastRayPosition = rayPos;
|
_player->idle();
|
||||||
rayPos += rayStep;
|
|
||||||
height = _terrain->getHeight(rayPos.x,rayPos.z);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
Vec3 startPosition = lastRayPosition;
|
|
||||||
Vec3 endPosition = rayPos;
|
|
||||||
|
|
||||||
for (int i= 0; i< 32; i++)
|
|
||||||
{
|
{
|
||||||
// Binary search pass
|
dir = collisionPoint - _player->getPosition3D();
|
||||||
Vec3 middlePoint = (startPosition + endPosition) * 0.5f;
|
dir.y = 0;
|
||||||
if (middlePoint.y < height)
|
dir.normalize();
|
||||||
endPosition = middlePoint;
|
_player->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
|
||||||
else
|
dir.cross(dir,Vec3(0,0,-1),&_player->_headingAxis);
|
||||||
startPosition = middlePoint;
|
_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();
|
event->stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue