mirror of https://github.com/axmolengine/axmol.git
Merge pull request #12019 from super626/v3
getIntersectionPoint failed when there is no intersection on the terrain
This commit is contained in:
commit
c5ba7eef8b
|
@ -278,7 +278,7 @@ void Terrain::setChunksLOD(Vec3 cameraPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Terrain::getHeight(float x, float z, Vec3 * normal)
|
float Terrain::getHeight(float x, float z, Vec3 * normal) const
|
||||||
{
|
{
|
||||||
Vec2 pos(x,z);
|
Vec2 pos(x,z);
|
||||||
|
|
||||||
|
@ -307,6 +307,10 @@ float Terrain::getHeight(float x, float z, Vec3 * normal)
|
||||||
|
|
||||||
if(image_x>=_imageWidth-1 || image_y >=_imageHeight-1 || image_x<0 || image_y<0)
|
if(image_x>=_imageWidth-1 || image_y >=_imageHeight-1 || image_x<0 || image_y<0)
|
||||||
{
|
{
|
||||||
|
if (normal)
|
||||||
|
{
|
||||||
|
normal->setZero();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
|
@ -327,12 +331,12 @@ float Terrain::getHeight(float x, float z, Vec3 * normal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Terrain::getHeight(Vec2 pos, Vec3*Normal)
|
float Terrain::getHeight(Vec2 pos, Vec3*Normal) const
|
||||||
{
|
{
|
||||||
return getHeight(pos.x,pos.y,Normal);
|
return getHeight(pos.x,pos.y,Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Terrain::getImageHeight(int pixel_x,int pixel_y)
|
float Terrain::getImageHeight(int pixel_x,int pixel_y) const
|
||||||
{
|
{
|
||||||
int byte_stride =1;
|
int byte_stride =1;
|
||||||
switch (_heightMapImage->getRenderFormat())
|
switch (_heightMapImage->getRenderFormat())
|
||||||
|
@ -472,7 +476,7 @@ Terrain::~Terrain()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::Vec3 Terrain::getNormal(int pixel_x, int pixel_y)
|
cocos2d::Vec3 Terrain::getNormal(int pixel_x, int pixel_y) const
|
||||||
{
|
{
|
||||||
float a = getImageHeight(pixel_x,pixel_y)*getScaleY();
|
float a = getImageHeight(pixel_x,pixel_y)*getScaleY();
|
||||||
float b = getImageHeight(pixel_x,pixel_y+1)*getScaleY();
|
float b = getImageHeight(pixel_x,pixel_y+1)*getScaleY();
|
||||||
|
@ -486,7 +490,7 @@ cocos2d::Vec3 Terrain::getNormal(int pixel_x, int pixel_y)
|
||||||
return normal;
|
return normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::Vec3 Terrain::getIntersectionPoint(const Ray & ray)
|
cocos2d::Vec3 Terrain::getIntersectionPoint(const Ray & ray) const
|
||||||
{
|
{
|
||||||
Vec3 dir = ray._direction;
|
Vec3 dir = ray._direction;
|
||||||
dir.normalize();
|
dir.normalize();
|
||||||
|
@ -496,12 +500,14 @@ cocos2d::Vec3 Terrain::getIntersectionPoint(const Ray & ray)
|
||||||
Vec3 lastRayPosition =rayPos;
|
Vec3 lastRayPosition =rayPos;
|
||||||
rayPos += rayStep;
|
rayPos += rayStep;
|
||||||
// Linear search - Loop until find a point inside and outside the terrain Vector3
|
// Linear search - Loop until find a point inside and outside the terrain Vector3
|
||||||
float height = getHeight(rayPos.x,rayPos.z);
|
Vec3 normal;
|
||||||
|
float height = getHeight(rayPos.x, rayPos.z, &normal);
|
||||||
while (rayPos.y > height)
|
while (rayPos.y > height)
|
||||||
{
|
{
|
||||||
lastRayPosition = rayPos;
|
lastRayPosition = rayPos;
|
||||||
rayPos += rayStep;
|
rayPos += rayStep;
|
||||||
|
if (normal.isZero())
|
||||||
|
return Vec3(0, 0, 0);
|
||||||
height = getHeight(rayPos.x,rayPos.z);
|
height = getHeight(rayPos.x,rayPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +527,47 @@ cocos2d::Vec3 Terrain::getIntersectionPoint(const Ray & ray)
|
||||||
return collisionPoint;
|
return collisionPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Terrain::getIntersectionPoint(const Ray & ray, Vec3 & intersectionPoint) const
|
||||||
|
{
|
||||||
|
Vec3 dir = ray._direction;
|
||||||
|
dir.normalize();
|
||||||
|
Vec3 rayStep = _terrainData._chunkSize.width*0.25*dir;
|
||||||
|
Vec3 rayPos = ray._origin;
|
||||||
|
Vec3 rayStartPosition = ray._origin;
|
||||||
|
Vec3 lastRayPosition = rayPos;
|
||||||
|
rayPos += rayStep;
|
||||||
|
// Linear search - Loop until find a point inside and outside the terrain Vector3
|
||||||
|
Vec3 normal;
|
||||||
|
float height = getHeight(rayPos.x, rayPos.z, &normal);
|
||||||
|
while (rayPos.y > height)
|
||||||
|
{
|
||||||
|
lastRayPosition = rayPos;
|
||||||
|
rayPos += rayStep;
|
||||||
|
if (normal.isZero())
|
||||||
|
{
|
||||||
|
intersectionPoint = Vec3(0, 0, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
height = getHeight(rayPos.x, rayPos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 startPosition = lastRayPosition;
|
||||||
|
Vec3 endPosition = rayPos;
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
// Binary search pass
|
||||||
|
Vec3 middlePoint = (startPosition + endPosition) * 0.5f;
|
||||||
|
if (middlePoint.y < height)
|
||||||
|
endPosition = middlePoint;
|
||||||
|
else
|
||||||
|
startPosition = middlePoint;
|
||||||
|
}
|
||||||
|
Vec3 collisionPoint = (startPosition + endPosition) * 0.5f;
|
||||||
|
intersectionPoint = collisionPoint;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Terrain::setMaxDetailMapAmount(int max_value)
|
void Terrain::setMaxDetailMapAmount(int max_value)
|
||||||
{
|
{
|
||||||
_maxDetailMapValue = max_value;
|
_maxDetailMapValue = max_value;
|
||||||
|
|
|
@ -302,22 +302,22 @@ public:
|
||||||
* @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip.
|
* @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip.
|
||||||
* @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0;
|
* @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0;
|
||||||
**/
|
**/
|
||||||
float getHeight(float x, float z, Vec3 * normal= nullptr);
|
float getHeight(float x, float z, Vec3 * normal= nullptr) const;
|
||||||
|
|
||||||
/**get specified position's height mapping to the terrain,use bi-linear interpolation method
|
/**get specified position's height mapping to the terrain,use bi-linear interpolation method
|
||||||
* @param pos the position (X,Z)
|
* @param pos the position (X,Z)
|
||||||
* @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip.
|
* @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip.
|
||||||
* @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0;
|
* @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0;
|
||||||
**/
|
**/
|
||||||
float getHeight(Vec2 pos, Vec3*Normal = nullptr);
|
float getHeight(Vec2 pos, Vec3*Normal = nullptr) const;
|
||||||
|
|
||||||
/**get the normal of the specified pistion in terrain
|
/**get the normal of the specified pistion in terrain
|
||||||
* @return the normal vector of the specified position of the terrain.
|
* @return the normal vector of the specified position of the terrain.
|
||||||
* @note the fast normal calculation may not get precise normal vector.
|
* @note the fast normal calculation may not get precise normal vector.
|
||||||
**/
|
**/
|
||||||
Vec3 getNormal(int pixelX, int pixelY);
|
Vec3 getNormal(int pixelX, int pixelY) const;
|
||||||
/**get height from the raw height filed*/
|
/**get height from the raw height filed*/
|
||||||
float getImageHeight(int pixelX, int pixelY);
|
float getImageHeight(int pixelX, int pixelY) const;
|
||||||
/**show the wireline instead of the surface,Debug Use only.
|
/**show the wireline instead of the surface,Debug Use only.
|
||||||
* @Note only support desktop platform
|
* @Note only support desktop platform
|
||||||
**/
|
**/
|
||||||
|
@ -344,7 +344,15 @@ public:
|
||||||
* Ray-Terrain intersection.
|
* Ray-Terrain intersection.
|
||||||
* @return the intersection point
|
* @return the intersection point
|
||||||
*/
|
*/
|
||||||
Vec3 getIntersectionPoint(const Ray & ray);
|
Vec3 getIntersectionPoint(const Ray & ray) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ray-Terrain intersection.
|
||||||
|
* @param ray to hit the terrain
|
||||||
|
* @param intersectionPoint hit point if hitted
|
||||||
|
* @return true if hit, false otherwise
|
||||||
|
*/
|
||||||
|
bool getIntersectionPoint(const Ray & ray, Vec3 & intersectionPoint) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the MaxDetailAmount.
|
* set the MaxDetailAmount.
|
||||||
|
|
|
@ -67,6 +67,16 @@ Physics3DWorld* Physics3DWorld::create(Physics3DWorldDes* info)
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Physics3DWorld::setGravity(const Vec3& gravity)
|
||||||
|
{
|
||||||
|
_btPhyiscsWorld->setGravity(convertVec3TobtVector3(gravity));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 Physics3DWorld::getGravity() const
|
||||||
|
{
|
||||||
|
return convertbtVector3ToVec3(_btPhyiscsWorld->getGravity());
|
||||||
|
}
|
||||||
|
|
||||||
bool Physics3DWorld::init(Physics3DWorldDes* info)
|
bool Physics3DWorld::init(Physics3DWorldDes* info)
|
||||||
{
|
{
|
||||||
///collision configuration contains default setup for memory, collision setup
|
///collision configuration contains default setup for memory, collision setup
|
||||||
|
|
|
@ -90,6 +90,12 @@ public:
|
||||||
*/
|
*/
|
||||||
static Physics3DWorld* create(Physics3DWorldDes* info);
|
static Physics3DWorld* create(Physics3DWorldDes* info);
|
||||||
|
|
||||||
|
/** set gravity for the physics world */
|
||||||
|
void setGravity(const Vec3& gravity);
|
||||||
|
|
||||||
|
/** get current gravity */
|
||||||
|
Vec3 getGravity() const;
|
||||||
|
|
||||||
/** Add a Physics3DObject. */
|
/** Add a Physics3DObject. */
|
||||||
void addPhysics3DObject(Physics3DObject* physicsObj);
|
void addPhysics3DObject(Physics3DObject* physicsObj);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue