Merge pull request #126 from songchengjiang/billboard

Billboard
This commit is contained in:
XiaoYang 2014-09-03 18:12:08 +08:00
commit 58f4e84b9a
3 changed files with 67 additions and 14 deletions

View File

@ -33,6 +33,7 @@ NS_CC_BEGIN
BillBorad::BillBorad()
: _zDepthInView(0.0f)
, _mode(Mode::View_Oriented)
{
}
@ -41,11 +42,12 @@ BillBorad::~BillBorad()
{
}
BillBorad* BillBorad::createWithTexture(Texture2D *texture)
BillBorad* BillBorad::createWithTexture(Texture2D *texture, Mode mode)
{
BillBorad *billborad = new (std::nothrow) BillBorad();
if (billborad && billborad->initWithTexture(texture))
{
billborad->_mode = mode;
billborad->autorelease();
return billborad;
}
@ -54,11 +56,12 @@ BillBorad* BillBorad::createWithTexture(Texture2D *texture)
}
BillBorad* BillBorad::create(const std::string& filename)
BillBorad* BillBorad::create(const std::string& filename, Mode mode)
{
BillBorad *billborad = new (std::nothrow) BillBorad();
if (billborad && billborad->initWithFile(filename))
{
billborad->_mode = mode;
billborad->autorelease();
return billborad;
}
@ -66,11 +69,12 @@ BillBorad* BillBorad::create(const std::string& filename)
return nullptr;
}
BillBorad* BillBorad::create(const std::string& filename, const Rect& rect)
BillBorad* BillBorad::create(const std::string& filename, const Rect& rect, Mode mode)
{
BillBorad *billborad = new (std::nothrow) BillBorad();
if (billborad && billborad->initWithFile(filename, rect))
{
billborad->_mode = mode;
billborad->autorelease();
return billborad;
}
@ -78,11 +82,12 @@ BillBorad* BillBorad::create(const std::string& filename, const Rect& rect)
return nullptr;
}
BillBorad* BillBorad::create()
BillBorad* BillBorad::create(Mode mode)
{
BillBorad *billborad = new (std::nothrow) BillBorad();
if (billborad && billborad->init())
{
billborad->_mode = mode;
billborad->autorelease();
return billborad;
}
@ -97,14 +102,25 @@ void BillBorad::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
const Mat4& camWorldMat = camera->getNodeToWorldTransform();
if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_transform.m, transform.m, sizeof(float) * 16) != 0)
{
Vec3 camDir(transform.m[12] - camWorldMat.m[12], transform.m[13] - camWorldMat.m[13], transform.m[14] - camWorldMat.m[14]);
Vec3 camDir;
switch (_mode)
{
case Mode::View_Oriented:
camDir = Vec3(transform.m[12] - camWorldMat.m[12], transform.m[13] - camWorldMat.m[13], transform.m[14] - camWorldMat.m[14]);
break;
case Mode::View_Plane_Oriented:
camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
break;
default:
break;
}
if (camDir.length() < MATH_TOLERANCE)
{
camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
}
camDir.normalize();
static Vec3 upAxis(0.0f, 1.0f, 0.0f);
Vec3 x, y;
camWorldMat.transformVector(upAxis, &y);
@ -114,12 +130,12 @@ void BillBorad::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
float xlen = sqrtf(transform.m[0] * transform.m[0] + transform.m[1] * transform.m[1] + transform.m[2] * transform.m[2]);
float ylen = sqrtf(transform.m[4] * transform.m[4] + transform.m[5] * transform.m[5] + transform.m[6] * transform.m[6]);
float zlen = sqrtf(transform.m[8] * transform.m[8] + transform.m[9] * transform.m[9] + transform.m[10] * transform.m[10]);
_billboardTransform.m[0] = x.x * xlen; _billboardTransform.m[1] = x.y * xlen; _billboardTransform.m[2] = x.z * xlen;
_billboardTransform.m[4] = y.x * ylen; _billboardTransform.m[5] = y.y * ylen; _billboardTransform.m[6] = y.z * ylen;
_billboardTransform.m[8] = -camDir.x * zlen; _billboardTransform.m[9] = -camDir.y * zlen; _billboardTransform.m[10] = -camDir.z * zlen;
_billboardTransform.m[12] = transform.m[12]; _billboardTransform.m[13] = transform.m[13]; _billboardTransform.m[14] = transform.m[14];
const Mat4 &viewMat = camWorldMat.getInversed();
_zDepthInView = -(viewMat.m[2] * transform.m[12] + viewMat.m[6] * transform.m[13] + viewMat.m[10] * transform.m[14] + viewMat.m[14]);
_transform = transform;
@ -133,4 +149,14 @@ void BillBorad::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
}
}
void BillBorad::setMode( Mode mode )
{
_mode = mode;
}
BillBorad::Mode BillBorad::getMode() const
{
return _mode;
}
NS_CC_END

View File

@ -36,6 +36,11 @@ class CC_DLL BillBorad : public Sprite
{
public:
enum class Mode
{
View_Oriented,
View_Plane_Oriented
};
/// @{
/// @name Creators
@ -44,7 +49,7 @@ public:
*
* @return An autoreleased BillBorad object.
*/
static BillBorad* create();
static BillBorad* create(Mode mode = Mode::View_Oriented);
/**
* Creates a BillBorad with an image filename.
@ -55,7 +60,7 @@ public:
* @param filename A path to image file, e.g., "scene1/monster.png"
* @return An autoreleased BillBorad object.
*/
static BillBorad* create(const std::string& filename);
static BillBorad* create(const std::string& filename, Mode mode = Mode::View_Oriented);
/**
* Creates a BillBorad with an image filename and a rect.
@ -64,7 +69,7 @@ public:
* @param rect A subrect of the image file
* @return An autoreleased BillBorad object
*/
static BillBorad* create(const std::string& filename, const Rect& rect);
static BillBorad* create(const std::string& filename, const Rect& rect, Mode mode = Mode::View_Oriented);
/**
* Creates a BillBorad with a Texture2D object.
@ -74,7 +79,13 @@ public:
* @param texture A pointer to a Texture2D object.
* @return An autoreleased BillBorad object
*/
static BillBorad* createWithTexture(Texture2D *texture);
static BillBorad* createWithTexture(Texture2D *texture, Mode mode = Mode::View_Oriented);
/** Set the billboard rotation mode. */
void setMode(Mode mode);
/** Get the billboard rotation mode. */
Mode getMode() const;
//override
/** draw BillBorad object */
@ -93,6 +104,8 @@ protected:
float _zDepthInView;
Mode _mode;
private:
CC_DISALLOW_COPY_AND_ASSIGN(BillBorad);

View File

@ -1600,6 +1600,20 @@ BillBoardTest::BillBoardTest()
}
}
std::string imgs[3] = {"Images/Icon.png", "Images/r2.png"};
for (unsigned int i = 0; i < 4; ++i)
{
Layer *layer = Layer::create();
auto billborad = BillBorad::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
billborad->setScale(0.5f);
billborad->setPosition3D(Vec3(0.0f, 0.0f, CCRANDOM_MINUS1_1() * 150.0f));
billborad->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
billborad->setOpacity(CCRANDOM_0_1() * 128 + 128);
layer->addChild(billborad);
_layerBillBorad->addChild(layer);
layer->runAction( RepeatForever::create( RotateBy::create( CCRANDOM_0_1(), Vec3(0.0f, 45.0f, 0.0f) ) ) );
}
addNewBillBoradWithCoords(Vec3(20,5,0));
addNewBillBoradWithCoords(Vec3(60,5,0));
addNewBillBoradWithCoords(Vec3(100,5,0));
@ -1647,10 +1661,10 @@ void BillBoardTest::addNewBillBoradWithCoords(Vec3 p)
{
auto billborad = BillBorad::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
billborad->setScale(0.5f);
_layerBillBorad->addChild(billborad);
billborad->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
billborad->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
billborad->setOpacity(CCRANDOM_0_1() * 128 + 128);
_layerBillBorad->addChild(billborad);
}
}
void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)