mirror of https://github.com/axmolengine/axmol.git
update terrain test add new method to get normal
This commit is contained in:
parent
d6c3320d49
commit
9ec366a130
|
@ -99,9 +99,9 @@ NS_CC_BEGIN
|
|||
|
||||
bool Terrain::init()
|
||||
{
|
||||
_lodDistance[0]=96;
|
||||
_lodDistance[1]=288;
|
||||
_lodDistance[2]=480;
|
||||
_lodDistance[0]=288;
|
||||
_lodDistance[1]=512;
|
||||
_lodDistance[2]=1000;
|
||||
auto shader = GLProgram::createWithByteArrays(vertex_shader,fragment_shader_RGB_4_DETAIL);
|
||||
auto state = GLProgramState::create(shader);
|
||||
setGLProgramState(state);
|
||||
|
@ -241,12 +241,12 @@ void Terrain::setChunksLOD(Vec3 cameraPos)
|
|||
}
|
||||
}
|
||||
|
||||
float Terrain::getHeight(float x, float y ,float z)
|
||||
float Terrain::getHeight(float x, float y ,float z,Vec3 * normal)
|
||||
{
|
||||
Vec2 pos = Vec2(x,z);
|
||||
|
||||
//top-left
|
||||
Vec2 tl = Vec2(-1*_terrainData.mapScale*imageWidth/2,-1*_terrainData.mapScale*imageWidth/2);
|
||||
Vec2 tl = Vec2(-1*_terrainData.mapScale*imageWidth/2,-1*_terrainData.mapScale*imageHeight/2);
|
||||
auto result = getNodeToWorldTransform()*Vec4(tl.x,0.0f,tl.y,1.0f);
|
||||
tl = Vec2(result.x,result.z);
|
||||
|
||||
|
@ -266,19 +266,33 @@ float Terrain::getHeight(float x, float y ,float z)
|
|||
float v =image_y - (int)image_y;
|
||||
float i = (int)image_x;
|
||||
float j = (int)image_y;
|
||||
|
||||
|
||||
if(image_x>=imageWidth-1 || image_y >=imageHeight-1 || image_x<0 || image_y<0)
|
||||
{
|
||||
return y;
|
||||
}else
|
||||
{
|
||||
float a = getImageHeight(i,j)*getScaleY();
|
||||
float b = getImageHeight(i,j+1)*getScaleY();
|
||||
float c = getImageHeight(i+1,j)*getScaleY();
|
||||
float d = getImageHeight(i+1,j+1)*getScaleY();
|
||||
if(normal)
|
||||
{
|
||||
normal->x = c - b;
|
||||
normal->y = 2;
|
||||
normal->z = d - a;
|
||||
normal->normalize();
|
||||
//(*normal) = (1-u)*(1-v)*getNormal(i,j)+ (1-u)*v*getNormal(i,j+1) + u*(1-v)*getNormal(i+1,j)+ u*v*getNormal(i+1,j+1);
|
||||
}
|
||||
float reuslt = (1-u)*(1-v)*getImageHeight(i,j)*getScaleY() + (1-u)*v*getImageHeight(i,j+1)*getScaleY() + u*(1-v)*getImageHeight(i+1,j)*getScaleY() + u*v*getImageHeight(i+1,j+1)*getScaleY();
|
||||
return reuslt;
|
||||
}
|
||||
}
|
||||
|
||||
float Terrain::getHeight(Vec3 pos)
|
||||
float Terrain::getHeight(Vec3 pos,Vec3*Normal)
|
||||
{
|
||||
return getHeight(pos.x,pos.y,pos.z);
|
||||
return getHeight(pos.x,pos.y,pos.z,Normal);
|
||||
}
|
||||
|
||||
float Terrain::getImageHeight(int pixel_x,int pixel_y)
|
||||
|
@ -387,6 +401,20 @@ Terrain::~Terrain()
|
|||
free(_chunkesArray);
|
||||
}
|
||||
|
||||
cocos2d::Vec3 Terrain::getNormal(int pixel_x,int pixel_y)
|
||||
{
|
||||
float a = getImageHeight(pixel_x,pixel_y)*getScaleY();
|
||||
float b = getImageHeight(pixel_x,pixel_y+1)*getScaleY();
|
||||
float c = getImageHeight(pixel_x+1,pixel_y)*getScaleY();
|
||||
float d = getImageHeight(pixel_x+1,pixel_y+1)*getScaleY();
|
||||
Vec3 normal;
|
||||
normal.x = c - b;
|
||||
normal.y = 2;
|
||||
normal.z = d - a;
|
||||
normal.normalize();
|
||||
return normal;
|
||||
}
|
||||
|
||||
void Terrain::Chunk::finish()
|
||||
{
|
||||
//genearate two VBO ,the first for vertices, we just setup datas once ,won't changed at all
|
||||
|
|
|
@ -193,9 +193,9 @@ public:
|
|||
/*create entry*/
|
||||
static Terrain * create(TerrainData ¶meter);
|
||||
/*get specified position's height mapping to the terrain*/
|
||||
float getHeight(float x, float y, float z);
|
||||
float getHeight(Vec3 pos);
|
||||
|
||||
float getHeight(float x, float y, float z,Vec3 * normal = NULL);
|
||||
float getHeight(Vec3 pos,Vec3 * nromal = NULL);
|
||||
Vec3 getNormal(int pixel_x,int pixel_y);
|
||||
/*get height from the raw height map*/
|
||||
float getImageHeight(int pixel_x,int pixel_y);
|
||||
/*Debug Use only, show the wireline instead of the surface. only support desktop platform*/
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
|
||||
|
||||
Vec3 camera_offset(0,30,90);
|
||||
|
||||
Vec3 camera_offset(0,45,60);
|
||||
#define PLAYER_HEIGHT 0
|
||||
static std::function<Layer*()> createFunctions[] =
|
||||
{
|
||||
CL(TerrainSimple),
|
||||
|
@ -44,7 +44,7 @@ TerrainSimple::TerrainSimple()
|
|||
Size visibleSize = Director::getInstance()->getVisibleSize();
|
||||
|
||||
//use custom camera
|
||||
auto camera = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1,200);
|
||||
auto camera = Camera::createPerspective(60,visibleSize.width/visibleSize.height,0.1,500);
|
||||
camera->setCameraFlag(CameraFlag::USER1);
|
||||
addChild(camera);
|
||||
|
||||
|
@ -150,7 +150,7 @@ TerrainWalkThru::TerrainWalkThru()
|
|||
_camera->setCameraFlag(CameraFlag::USER1);
|
||||
addChild(_camera);
|
||||
|
||||
Terrain::TerrainData a("TerrainTest/heightmap16.jpg","TerrainTest/sand.jpg");
|
||||
Terrain::TerrainData a("TerrainTest/heightmap16.jpg","TerrainTest/sand.jpg",Size(32,32),3);
|
||||
_terrain = Terrain::create(a);
|
||||
_terrain->setScale(20);
|
||||
|
||||
|
@ -159,14 +159,21 @@ TerrainWalkThru::TerrainWalkThru()
|
|||
|
||||
_action = new PlayerAction(_camera,_terrain);
|
||||
_action->retain();
|
||||
_player =Sprite3D::create("Sprite3DTest/orc.c3b");
|
||||
_player =Sprite3D::create("Sprite3DTest/girl.c3b");
|
||||
_player->runAction(_action);
|
||||
_player->setCameraMask(2);
|
||||
//_player->setScale(0.1);
|
||||
_player->setPositionY(_terrain->getHeight(_player->getPosition3D()));
|
||||
_player->setScale(0.08);
|
||||
_player->setPositionY(_terrain->getHeight(_player->getPosition3D())+PLAYER_HEIGHT);
|
||||
|
||||
auto animation = Animation3D::create("Sprite3DTest/girl.c3b","Take 001");
|
||||
if (animation)
|
||||
{
|
||||
auto animate = Animate3D::create(animation);
|
||||
_player->runAction(RepeatForever::create(animate));
|
||||
}
|
||||
|
||||
_camera->setPosition3D(_player->getPosition3D()+camera_offset);
|
||||
_camera->setRotation3D(Vec3(-15,0,0));
|
||||
_camera->setRotation3D(Vec3(-45,0,0));
|
||||
|
||||
forward = Label::create("forward","arial",22);
|
||||
forward->setPosition(0,200);
|
||||
|
@ -184,10 +191,6 @@ TerrainWalkThru::TerrainWalkThru()
|
|||
right = Label::create("turn right","arial",22);
|
||||
right->setPosition(0,150);
|
||||
right->setAnchorPoint(Vec2(0,0));
|
||||
addChild(forward);
|
||||
addChild(backward);
|
||||
addChild(left);
|
||||
addChild(right);
|
||||
addChild(_player);
|
||||
addChild(_terrain);
|
||||
}
|
||||
|
@ -216,40 +219,6 @@ void TerrainWalkThru::onTouchesMoved(const std::vector<cocos2d::Touch*>& touches
|
|||
|
||||
void TerrainWalkThru::onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
|
||||
{
|
||||
auto touch = touches[0];
|
||||
Size s = left->getContentSize();
|
||||
Rect rect = Rect(left->getPositionX(), left->getPositionY(), s.width, s.height);
|
||||
auto location = touch->getLocation();
|
||||
if(rect.containsPoint(location))
|
||||
{
|
||||
//turn left
|
||||
_action->turnLeft();
|
||||
}
|
||||
|
||||
s = right->getContentSize();
|
||||
rect = Rect(right->getPositionX(), right->getPositionY(), s.width, s.height);
|
||||
if(rect.containsPoint(location))
|
||||
{
|
||||
//turn right
|
||||
_action->turnRight();
|
||||
}
|
||||
|
||||
s = forward->getContentSize();
|
||||
rect = Rect(forward->getPositionX(), forward->getPositionY(), s.width, s.height);
|
||||
if(rect.containsPoint(location))
|
||||
{
|
||||
//forward
|
||||
_action->forward();
|
||||
}
|
||||
|
||||
s = backward->getContentSize();
|
||||
rect = Rect(backward->getPositionX(), backward->getPositionY(), s.width, s.height);
|
||||
if(rect.containsPoint(location))
|
||||
{
|
||||
//backward
|
||||
_action->backward();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TerrainWalkThru::onTouchesEnd(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
|
||||
|
@ -296,7 +265,11 @@ void TerrainWalkThru::onTouchesEnd(const std::vector<cocos2d::Touch*>& touches,
|
|||
startPosition = middlePoint;
|
||||
}
|
||||
Vec3 collisionPoint = (startPosition + endPosition) * 0.5f;
|
||||
|
||||
dir = collisionPoint - _player->getPosition3D();
|
||||
dir.y = 0;
|
||||
dir.normalize();
|
||||
_action->_headingAngle = -1*acos(dir.dot(Vec3(0,0,-1)));
|
||||
dir.cross(dir,Vec3(0,0,-1),&_action->_headingAxis);
|
||||
_action->_targetPos=collisionPoint;
|
||||
_action->forward();
|
||||
}
|
||||
|
@ -326,7 +299,6 @@ void PlayerAction::step(float dt)
|
|||
Vec3 offset = newFaceDir * 25.0f * dt;
|
||||
curPos+=offset;
|
||||
player->setPosition3D(curPos);
|
||||
player->setPositionY(_terrain->getHeight(player->getPosition3D()));
|
||||
}
|
||||
break;
|
||||
case PLAYER_STATE_BACKWARD:
|
||||
|
@ -335,7 +307,6 @@ void PlayerAction::step(float dt)
|
|||
player->getNodeToWorldTransform().getForwardVector(&forward_vec);
|
||||
forward_vec.normalize();
|
||||
player->setPosition3D(player->getPosition3D()-forward_vec*15*dt);
|
||||
player->setPositionY(_terrain->getHeight(player->getPosition3D()));
|
||||
}
|
||||
break;
|
||||
case PLAYER_STATE_LEFT:
|
||||
|
@ -351,10 +322,21 @@ void PlayerAction::step(float dt)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
Vec3 Normal;
|
||||
float player_h = _terrain->getHeight(player->getPosition3D(),&Normal);
|
||||
float dot_product = Normal.dot(Vec3(0,1,0));
|
||||
|
||||
player->setPositionY(player_h+PLAYER_HEIGHT);
|
||||
Quaternion q2;
|
||||
q2.createFromAxisAngle(Vec3(0,1,0),-M_PI,&q2);
|
||||
|
||||
Quaternion headingQ;
|
||||
headingQ.createFromAxisAngle(_headingAxis,_headingAngle,&headingQ);
|
||||
player->setRotationQuat(headingQ*q2);
|
||||
auto vec_offset =Vec4(camera_offset.x,camera_offset.y,camera_offset.z,1);
|
||||
vec_offset = player->getNodeToWorldTransform()*vec_offset;
|
||||
_cam->setRotation3D(player->getRotation3D());
|
||||
_cam->setPosition3D(Vec3(vec_offset.x,vec_offset.y,vec_offset.z));
|
||||
// _cam->setRotation3D(player->getRotation3D());
|
||||
_cam->setPosition3D(player->getPosition3D() + camera_offset);
|
||||
updateState();
|
||||
}
|
||||
|
||||
|
@ -375,6 +357,7 @@ void PlayerAction::idle()
|
|||
|
||||
PlayerAction::PlayerAction(Camera * cam,Terrain * terrain)
|
||||
{
|
||||
_headingAngle = 0;
|
||||
_playerState = PLAYER_STATE_IDLE;
|
||||
_cam = cam;
|
||||
_terrain = terrain;
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
void idle();
|
||||
cocos2d::Vec3 _targetPos;
|
||||
void updateState();
|
||||
float _headingAngle;
|
||||
Vec3 _headingAxis;
|
||||
private:
|
||||
Terrain * _terrain;
|
||||
Camera * _cam;
|
||||
|
|
Loading…
Reference in New Issue