diff --git a/cocos/3d/CCBillBoard.cpp b/cocos/3d/CCBillBoard.cpp index db9240b2e1..ee5d4437c8 100644 --- a/cocos/3d/CCBillBoard.cpp +++ b/cocos/3d/CCBillBoard.cpp @@ -93,36 +93,42 @@ BillBorad* BillBorad::create() void BillBorad::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) { auto camera = Camera::getVisitingCamera(); - const Mat4 &viewMat = camera->getViewMatrix(); -// const Mat4& camWorldMat = camera->getNodeToWorldTransform(); -// Vec3 camDir(transform.m[12] - camWorldMat.m[12], transform.m[13] - camWorldMat.m[13], transform.m[14] - camWorldMat.m[14]); -// camDir.normalize(); -// static Vec3 upAxis(0.0f, 1.0f, 0.0f); -// Vec3 x, y; -// camWorldMat.transformVector(upAxis, &y); -// Vec3::cross(camDir, y, &x); -// x.normalize(); -// Vec3::cross(x, camDir, &y); -// Mat4 newTransform; -// newTransform.m[0] = x.x; newTransform.m[1] = x.y; newTransform.m[2] = x.z; -// newTransform.m[4] = y.x; newTransform.m[5] = y.y; newTransform.m[6] = y.z; -// newTransform.m[8] = -camDir.x; newTransform.m[9] = -camDir.y; newTransform.m[10] = -camDir.z; -// newTransform.m[12] = transform.m[12]; newTransform.m[13] = transform.m[13]; newTransform.m[14] = transform.m[14]; - - if (memcmp(_preViewMat.m, viewMat.m, sizeof(float) * 16) != 0) + const Mat4& camWorldMat = camera->getNodeToWorldTransform(); + if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_transform.m, transform.m, sizeof(float) * 16) != 0) { - Mat4 viewInverseMat = camera->getInverseViewMatrix(); - viewInverseMat.m[12] = viewInverseMat.m[13] = viewInverseMat.m[14] = 0; - Mat4 modelViewMat = viewMat * transform; - _preViewMat = viewMat; - _zDepthInView = -modelViewMat.m[14]; - _mv = viewInverseMat; + Vec3 camDir(transform.m[12] - camWorldMat.m[12], transform.m[13] - camWorldMat.m[13], transform.m[14] - camWorldMat.m[14]); + + 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); + Vec3::cross(camDir, y, &x); + x.normalize(); + Vec3::cross(x, camDir, &y); + 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; + _camWorldMat = camWorldMat; } //FIXME: frustum culling here { - _quadCommand.init(_zDepthInView, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, newTransform/*transform * _mv*/); + _quadCommand.init(_zDepthInView, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _billboardTransform); renderer->addTransparentCommand(&_quadCommand); } } diff --git a/cocos/3d/CCBillBoard.h b/cocos/3d/CCBillBoard.h index 369c798d57..daf36bee4b 100644 --- a/cocos/3d/CCBillBoard.h +++ b/cocos/3d/CCBillBoard.h @@ -87,8 +87,10 @@ CC_CONSTRUCTOR_ACCESS: protected: - Mat4 _preViewMat; - Mat4 _mv; + Mat4 _camWorldMat; + Mat4 _transform; + Mat4 _billboardTransform; + float _zDepthInView; private: