Example #1
0
void PUBillboardChain::render( Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem )
{
    auto camera = Camera::getVisitingCamera();
    auto cameraMat = camera->getNodeToWorldTransform();

    if (!_chainSegmentList.empty())
    {
        updateVertexBuffer(cameraMat);
        updateIndexBuffer();
        if (!_vertices.empty() && !_indices.empty())
        {
            GLuint texId = this->getTextureName();
            _stateBlock->setBlendFunc(particleSystem->getBlendFunc());
            _meshCommand->init(0,
                               texId,
                               _glProgramState,
                               _stateBlock,
                               _vertexBuffer->getVBO(),
                               _indexBuffer->getVBO(),
                               GL_TRIANGLES,
                               GL_UNSIGNED_SHORT,
                               _indices.size(),
                               transform,
                               Node::FLAGS_RENDER_AS_3D);
            _meshCommand->setSkipBatching(true);
            _meshCommand->setTransparent(true);            
            _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1));
            renderer->addCommand(_meshCommand);
        }
    }
}
Example #2
0
wyRect wyNode::getBoundingBoxRelativeToWorld() {
    wyRect r = {
        0, 0, m_width, m_height
    };
    wyAffineTransform t = getNodeToWorldTransform();
    return wyaTransformRect(t, r);
}
Example #3
0
const AABB& Sprite3D::getAABB() const
{
    Mat4 nodeToWorldTransform(getNodeToWorldTransform());
    
    // If nodeToWorldTransform matrix isn't changed, we don't need to transform aabb.
    if (memcmp(_nodeToWorldTransform.m, nodeToWorldTransform.m, sizeof(Mat4)) == 0 && !_aabbDirty)
    {
        return _aabb;
    }
    else
    {
        _aabb.reset();
        if (_meshes.size())
        {
            Mat4 transform(nodeToWorldTransform);
            for (const auto& it : _meshes) {
                if (it->isVisible())
                    _aabb.merge(it->getAABB());
            }
            
            _aabb.transform(transform);
            _nodeToWorldTransform = nodeToWorldTransform;
            _aabbDirty = false;
        }
    }
    
    return _aabb;
}
Example #4
0
float Camera::getDepthInView(const Mat4& transform) const
{
    Mat4 camWorldMat = getNodeToWorldTransform();
    const Mat4 &viewMat = camWorldMat.getInversed();
    float depth = -(viewMat.m[2] * transform.m[12] + viewMat.m[6] * transform.m[13] + viewMat.m[10] * transform.m[14] + viewMat.m[14]);
    return depth;
}
Example #5
0
void Skybox::onDraw(const Mat4& transform, uint32_t flags)
{
    auto camera = Camera::getVisitingCamera();
    
    Mat4 cameraModelMat = camera->getNodeToWorldTransform();
    
    auto state = getGLProgramState();
    state->apply(transform);

    Vec4 color(_displayedColor.r / 255.f, _displayedColor.g / 255.f, _displayedColor.b / 255.f, 1.f);
    state->setUniformVec4("u_color", color);
    cameraModelMat.m[12] = cameraModelMat.m[13] = cameraModelMat.m[14] = 0;
    state->setUniformMat4("u_cameraRot", cameraModelMat);

    glEnable(GL_DEPTH_TEST);
    StateBlock::_defaultState->setDepthTest(true);

    glDepthFunc(GL_LEQUAL);
    StateBlock::_defaultState->setDepthFunction(DEPTH_LEQUAL);

    glEnable(GL_CULL_FACE);
    StateBlock::_defaultState->setCullFace(true);

    glCullFace(GL_BACK);
    StateBlock::_defaultState->setCullFaceSide(CULL_FACE_SIDE_BACK);
    
    glDisable(GL_BLEND);
    StateBlock::_defaultState->setBlend(false);

    if (Configuration::getInstance()->supportsShareableVAO())
    {
        GL::bindVAO(_vao);
    }
    else
    {
        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION);

        glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), nullptr);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    }

    glDrawElements(GL_TRIANGLES, (GLsizei)36, GL_UNSIGNED_BYTE, nullptr);

    if (Configuration::getInstance()->supportsShareableVAO())
    {
        GL::bindVAO(0);
    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 8);

    CHECK_GL_ERROR_DEBUG();
}
Example #6
0
void Hero::_armEventHandler(cocos2d::EventCustom* event)
{
    const auto eventObject = (dragonBones::EventObject*)event->getUserData();

    if (eventObject->type == dragonBones::EventObject::COMPLETE)
    {
        _isAttacking = false;
        _hitCount = 0;
        const auto animationName = "ready_" + _weaponName;
        _armArmature->getAnimation().fadeIn(animationName);
    }
    else if (eventObject->type == dragonBones::EventObject::FRAME_EVENT)
    {
        if (eventObject->name == "ready")
        {
            _isAttacking = false;
            _hitCount++;
        }
        else if (eventObject->name == "fire")
        {
            const auto display = (dragonBones::CCArmatureDisplay*)(eventObject->armature->getDisplay());
            const auto firePointBone = eventObject->armature->getBone("bow");
            const auto transform = display->getNodeToWorldTransform();
            cocos2d::Vec3 localPoint(firePointBone->global.x, -firePointBone->global.y, 0.f);
            cocos2d::Vec2 globalPoint;
            transform.transformPoint(&localPoint);
            globalPoint.set(localPoint.x, localPoint.y);

            auto radian = 0.f;
            if (_faceDir > 0)
            {
                radian = firePointBone->global.getRotation() + display->getRotation() * dragonBones::ANGLE_TO_RADIAN;
            }
            else
            {
                radian = dragonBones::PI - (firePointBone->global.getRotation() + display->getRotation() * dragonBones::ANGLE_TO_RADIAN);
            }

            switch (_weaponsLevel[_weaponIndex])
            {
            case 0:
                _fire(globalPoint, radian);
                break;

            case 1:
                _fire(globalPoint, radian + 3.f * dragonBones::ANGLE_TO_RADIAN);
                _fire(globalPoint, radian - 3.f * dragonBones::ANGLE_TO_RADIAN);
                break;

            case 2:
                _fire(globalPoint, radian + 6.f * dragonBones::ANGLE_TO_RADIAN);
                _fire(globalPoint, radian);
                _fire(globalPoint, radian - 6.f * dragonBones::ANGLE_TO_RADIAN);
                break;
            }
        }
    }
}
Example #7
0
Vec2 Node::convertToWorldSpace(const Vec2& nodePoint) const
{
    Mat4 tmp = getNodeToWorldTransform();
    Vec3 vec3(nodePoint.x, nodePoint.y, 0);
    Vec3 ret;
    tmp.transformPoint(vec3,&ret);
    return Vec2(ret.x, ret.y);

}
Example #8
0
Point Node::convertToWorldSpace(const Point& nodePoint) const
{
    kmMat4 tmp = getNodeToWorldTransform();
    kmVec3 vec3 = {nodePoint.x, nodePoint.y, 0};
    kmVec3 ret;
    kmVec3Transform(&ret, &vec3, &tmp);
    return Point(ret.x, ret.y);

}
Vec3 BillboardParticleSystem::convertToWorldSpace3D(const Vec3& nodePoint) const
{
    Mat4 tmp = getNodeToWorldTransform();
    Vec3 vec3(nodePoint.x, nodePoint.y, nodePoint.z);
    Vec3 ret;
    tmp.transformPoint(vec3,&ret);
    return Vec3(ret.x, ret.y,ret.z);

}
cocos2d::Vec3 PUParticleSystem3D::getDerivedPosition()
{
    //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Vec3::ZERO; 
    //if (_keepLocal) return Vec3::ZERO;
    if (_isMarkedForEmission){
        return Vec3(_position.x, _position.y, _positionZ);
    }else{
        Mat4 mat = getNodeToWorldTransform();
        return Vec3(mat.m[12], mat.m[13], mat.m[14]);
    }
}
Example #11
0
const Mat4& Camera::getViewMatrix() const
{
    Mat4 viewInv(getNodeToWorldTransform());
    static int count = sizeof(float) * 16;
    if (memcmp(viewInv.m, _viewInv.m, count) != 0)
    {
        _viewProjectionDirty = true;
        _viewInv = viewInv;
        _view = viewInv.getInversed();
    }
    return _view;
}
cocos2d::Quaternion PUParticleSystem3D::getDerivedOrientation()
{
    //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Quaternion(); 
    //if (_keepLocal) return Quaternion();
    if (_isMarkedForEmission){
        return getRotationQuat();
    }else{
        Quaternion q;
        Mat4 mat = getNodeToWorldTransform();
        mat.decompose(nullptr, &q, nullptr);
        return q;
    }
}
cocos2d::Vec3 PUParticleSystem3D::getDerivedScale()
{
    //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Vec3::ONE; 
    //if (_keepLocal) return Vec3::ONE;
    if (_isMarkedForEmission){
        return Vec3(_scaleX, _scaleY, _scaleZ);
    }else{
        Vec3 s;
        Mat4 mat = getNodeToWorldTransform();
        mat.decompose(&s, nullptr, nullptr);
        return s;
    }
}
Example #14
0
Mat4 AttachNode::getNodeToWorldTransform() const
{
    Mat4 mat;
    auto parent = getParent();
    if (parent)
    {
        mat = parent->getNodeToWorldTransform() * _attachBone->getWorldMat();
    }
    else
    {
        mat = _attachBone->getWorldMat();
    }
    return mat;
}
Example #15
0
void Gun::emitProjectile()
{
    GAFAnimatedObject* model = m_projectile->createObjectAndRun(true);
    model->setPosition(m_projectileOffset);

    Mat4 transform = getNodeToWorldTransform();

    Node* container = Node::create();
    container->setPosition(m_emissionPoint);
    addChild(container);
    Projectile* p = Projectile::create(model, m_projectileDamage, m_projectileSpeed, container);
    removeChild(container);

    Director::getInstance()->getRunningScene()->addChild(p);
}
Example #16
0
void Mecha::_frameEventHandler(cocos2d::EventCustom* event)
{
    const auto eventObject = (dragonBones::EventObject*)event->getUserData();
    if (eventObject->name == "onFire")
    {
        const auto display = (dragonBones::CCArmatureDisplay*)eventObject->armature->getDisplay();
        const auto firePointBone = eventObject->armature->getBone("firePoint");
        const auto transform = display->getNodeToWorldTransform();
        cocos2d::Vec3 localPoint(firePointBone->global.x, -firePointBone->global.y, 0.f);
        cocos2d::Vec2 globalPoint;
        transform.transformPoint(&localPoint);
        globalPoint.set(localPoint.x, localPoint.y);

        _fire(globalPoint);
    }
}
Example #17
0
void Player::update(float dt)
{
    Rect rect = m_model->realBoundingBoxForCurrentFrame();
    Vec3 scale, pos; Quaternion rot;
    getNodeToWorldTransform().decompose(&scale, &rot, &pos);

    do
    {
        Node* level = Director::getInstance()->getRunningScene()->getChildByTag(1);
        if (level == nullptr)
        {
            break;
        }
        Vec2 position = level->getPosition();
        if (m_state == EWalkLeft)
        {
            position += dt * m_speed * Vec2(scale.x, 0);
        }
        else if (m_state == EWalkRight)
        {
            position += dt * m_speed * Vec2(-scale.x, 0);
        }
        else
        {
            break;
        }
        level->setPosition(position);

    } while (0);

    Size boxSize(rect.size.width * scale.x, rect.size.height * scale.y);
    Vec2 boxPos(rect.origin.x * scale.x + boxSize.width / 2, rect.origin.y * scale.y + boxSize.height / 2);
    auto body = PhysicsBody::createBox(boxSize, PHYSICSBODY_MATERIAL_DEFAULT);
    body->setPositionOffset(boxPos);
    setPhysicsBody(body);
    body->setContactTestBitmask(0x2);

}
Example #18
0
void PUSphereRender::render( Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem )
{
    //batch and generate draw
    const ParticlePool &particlePool = particleSystem->getParticlePool();
    if (!_isVisible || particlePool.empty())
        return;

    auto camera = Camera::getVisitingCamera();
    auto cameraMat = camera->getNodeToWorldTransform();
    Vec3 backward(cameraMat.m[8], cameraMat.m[9], cameraMat.m[10]);

    unsigned int vertexCount = (_numberOfRings + 1) * (_numberOfSegments + 1);
    unsigned int indexCount = 6 * _numberOfRings * (_numberOfSegments + 1);
    if (_vertexBuffer == nullptr && _indexBuffer == nullptr) {
        GLsizei stride = sizeof(VertexInfo);
        _vertexBuffer = VertexBuffer::create(stride, vertexCount * particleSystem->getParticleQuota());
        if (_vertexBuffer == nullptr)
        {
            CCLOG("PUSphereRender::render create vertex buffer failed");
            return;
        }
        _vertexBuffer->retain();
        _vertices.resize(vertexCount * particleSystem->getParticleQuota());

        _indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, indexCount * particleSystem->getParticleQuota());
        if (_indexBuffer == nullptr)
        {
            CCLOG("PUSphereRender::render create index buffer failed");
            return;
        }
        _indexBuffer->retain();
        _indices.resize(indexCount * particleSystem->getParticleQuota());

        buildBuffers(particleSystem->getParticleQuota());
    }

    unsigned int vertexindex = 0;
    unsigned int index = 0;

    Mat4 mat;
    Mat4 rotMat;
    Mat4 sclMat;
    Mat4 texRot;
    Vec3 val;
    for (auto iter : particlePool.getActiveDataList())
    {
        auto particle = static_cast<PUParticle3D *>(iter);
        float radius = particle->width * 0.5f;
        Mat4::createRotation(particle->orientation, &rotMat);
        Mat4::createScale(radius, radius, radius, &sclMat);
        Mat4::createRotation(backward, particle->zRotation, &texRot);
        mat = rotMat * sclMat;
        mat.m[12] = particle->position.x;
        mat.m[13] = particle->position.y;
        mat.m[14] = particle->position.z;

        for (unsigned int i = 0; i < vertexCount; ++i) {
            val = texRot * Vec3(_vertexTemplate[vertexindex + i].uv.x, _vertexTemplate[vertexindex + i].uv.y, 0.0f);
            mat.transformPoint(_vertexTemplate[vertexindex + i].position, &_vertices[vertexindex + i].position);
            _vertices[vertexindex + i].color = particle->color;
            _vertices[vertexindex + i].uv.x = val.x;
            _vertices[vertexindex + i].uv.y = val.y;
        }
        vertexindex += vertexCount;
        index += indexCount;
    }

    if (!_vertices.empty() && !_indices.empty()) {
        _vertexBuffer->updateVertices(&_vertices[0], vertexindex/* * sizeof(_posuvcolors[0])*/, 0);
        _indexBuffer->updateIndices(&_indices[0], index/* * sizeof(unsigned short)*/, 0);

        GLuint texId = (_texture ? _texture->getName() : 0);
        _stateBlock->setBlendFunc(particleSystem->getBlendFunc());
        _meshCommand->init(
            0,
            texId,
            _glProgramState,
            _stateBlock,
            _vertexBuffer->getVBO(),
            _indexBuffer->getVBO(),
            GL_TRIANGLES,
            GL_UNSIGNED_SHORT,
            index,
            transform,
            Node::FLAGS_RENDER_AS_3D);
        _meshCommand->setSkipBatching(true);
        _meshCommand->setTransparent(true);

        _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1));
        renderer->addCommand(_meshCommand);
    }
}
Example #19
0
wyAffineTransform wyNode::getWorldToNodeTransform() {
    wyAffineTransform t = getNodeToWorldTransform();
    wyaInverse(&t);
    return t;
}
Example #20
0
wyPoint wyNode::nodeToWorldSpace(wyPoint p) {
    wyAffineTransform t = getNodeToWorldTransform();
    return wyaTransformPoint(t, p);
}
void BillboardParticleSystem::update(float dt)
{
    if(_camera)
    {
        const Mat4& cameraViewMatrix = _camera->getViewMatrix().getInversed();
        cameraViewMatrix.getRightVector(&_cameraRight);
        cameraViewMatrix.getUpVector(&_cameraUp);
    }
    const Mat4& WorldMat = getNodeToWorldTransform();
    Quaternion rotation;;
    WorldMat.getRotation(&rotation);
    Mat4 roaMat;
    Mat4::createRotation(rotation,&roaMat);

    CC_PROFILER_START_CATEGORY(kProfilerCategoryParticles , "CCParticleSystem - update");
    if (_isActive && _emissionRate)
    {
        float rate = 1.0f / _emissionRate;
        //issue #1201, prevent bursts of particles, due to too high emitCounter
        if (_particleCount < _totalParticles)
        {
            _emitCounter += dt;
        }

        while (_particleCount < _totalParticles && _emitCounter > rate) 
        {
            this->addParticle();
            _emitCounter -= rate;
        }

        _elapsed += dt;
        if (_duration != -1 && _duration < _elapsed)
        {
            this->stopSystem();
        }
    }

    _particleIdx = 0;

    Vec3 currentPosition = Vec3::ZERO;
    if (_positionType == PositionType::FREE)
    {
        currentPosition = this->convertToWorldSpace3D(Vec3::ZERO);
    }
    else if (_positionType == PositionType::RELATIVE)
    {
        currentPosition.x = _position.x;
        currentPosition.y = _position.y;
        currentPosition.z = _positionZ;
    }

    {
        while (_particleIdx < _particleCount)
        {
            sBillboardParticle *p = &_particles[_particleIdx];

            // life
            p->timeToLive -= dt;

            if (p->timeToLive > 0) 
            {
                // Mode A: gravity, direction, tangential accel & radial accel
                if (_emitterMode == Mode::GRAVITY)
                {
                    Vec2 tmp, radial, tangential;

                    radial = Vec2::ZERO;
                    // radial acceleration
                    if (p->pos.x || p->pos.y)
                    {
                        radial = p->pos.getNormalized();
                    }
                    tangential = radial;
                    radial = radial * p->modeA.radialAccel;

                    // tangential acceleration
                    float newy = tangential.x;
                    tangential.x = -tangential.y;
                    tangential.y = newy;
                    tangential = tangential * p->modeA.tangentialAccel;

                    // (gravity + radial + tangential) * dt
                    tmp = radial + tangential + modeA.gravity;
                    tmp = tmp * dt;
                    p->modeA.dir = p->modeA.dir + tmp;

                    // this is cocos2d-x v3.0
                    //                    if (_configName.length()>0 && _yCoordFlipped != -1)

                    // this is cocos2d-x v3.0
                    tmp = p->modeA.dir * dt * _yCoordFlipped;
                    p->pos = p->pos + tmp;
                }

                // Mode B: radius movement
                else 
                {                
                    // Update the angle and radius of the particle.
                    p->modeB.angle += p->modeB.degreesPerSecond * dt;
                    p->modeB.radius += p->modeB.deltaRadius * dt;

                    p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius;
                    p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius;
                    p->pos.y *= _yCoordFlipped;
                }

                // color
                p->color.r += (p->deltaColor.r * dt);
                p->color.g += (p->deltaColor.g * dt);
                p->color.b += (p->deltaColor.b * dt);
                p->color.a += (p->deltaColor.a * dt);

                // size
                p->size += (p->deltaSize * dt);
                p->size = MAX( 0, p->size );

                // angle
                p->rotation += (p->deltaRotation * dt);

                //
                // update values in quad
                //

                Vec3    newPos;
                Vec3 parPos(p->pos.x,p->pos.y,0);
                roaMat.transformVector(&parPos);
                if (_positionType == PositionType::FREE)
                {
                    Vec3 diff = convertToNodeSpace3D(currentPosition) - convertToNodeSpace3D(p->startPos);
                    //newPos.x =  p->pos.x - diff.x;
                    //newPos.y =  p->pos.y - diff.y;
                    //newPos.z = - diff.z;
                    newPos = parPos-diff;
                }
                else if(_positionType == PositionType::RELATIVE)
                {
                    Vec3 diff = currentPosition - p->startPos;
                    newPos.x = p->pos.x - diff.x;
                    newPos.y =  p->pos.y - diff.y;
                    newPos.z = - diff.z;
                } 
                else
                {
                    newPos.x = p->pos.x;
                    newPos.y = p->pos.y;
                    newPos.z = 0;
                }

                updateQuadWithParticle(p, newPos);
                //updateParticleImp(self, updateParticleSel, p, newPos);

                // update particle counter
                ++_particleIdx;
            } 
            else 
            {
                // life < 0
                int currentIndex = p->atlasIndex;
                if( _particleIdx != _particleCount-1 )
                {
                    _particles[_particleIdx] = _particles[_particleCount-1];
                }
                --_particleCount;

                if( _particleCount == 0 && _isAutoRemoveOnFinish )
                {
                    this->unscheduleUpdate();
                    _parent->removeChild(this, true);
                    return;
                }
            }
        } //while
        _transformSystemDirty = false;
    }

    // only update gl buffer when visible
    if (_visible)
    {
        postStep();
    }

    CC_PROFILER_STOP_CATEGORY(kProfilerCategoryParticles , "BillboardParticleSystem - update");
}
Example #22
0
void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    auto camera = Camera::getVisitingCamera();
    const Mat4& camWorldMat = camera->getNodeToWorldTransform();
    if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_mvTransform.m, transform.m, sizeof(float) * 16) != 0 || _modeDirty)
    {
        Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f);
        Mat4 localToWorld = transform;
        localToWorld.translate(anchorPoint);
        Vec3 camDir;
        switch (_mode)
        {
        case Mode::VIEW_POINT_ORIENTED:
            camDir = Vec3(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]);
            break;
        case Mode::VIEW_PLANE_ORIENTED:
            camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
            break;
        default:
                CCASSERT(false, "invalid billboard mode");
            break;
        }
        _modeDirty = false;
        if (camDir.length() < MATH_TOLERANCE)
        {
            camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
        }
        camDir.normalize();
        Quaternion rotationQuaternion;
        this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
        // fetch the rotation angle of z
        float rotationZ = atan2(2*(rotationQuaternion.w*rotationQuaternion.z + rotationQuaternion.x*rotationQuaternion.y),
            (1 - 2* (rotationQuaternion.y*rotationQuaternion.y + rotationQuaternion.z *rotationQuaternion.z)));
        Mat4 rotationMatrix;
        rotationMatrix.setIdentity();
        rotationMatrix.rotateZ(rotationZ);
        Vec3 upAxis = Vec3(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
        Vec3 x, y;
        camWorldMat.transformVector(upAxis, &y);
        Vec3::cross(camDir, y, &x);
        x.normalize();
        Vec3::cross(x, camDir, &y);
        y.normalize();

        float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]);
        float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]);
        float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.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] = localToWorld.m[12]; _billboardTransform.m[13] = localToWorld.m[13]; _billboardTransform.m[14] = localToWorld.m[14];

        _billboardTransform.translate(-anchorPoint);

        const Mat4 &viewMat = camWorldMat.getInversed();
        _zDepthInView = -(viewMat.m[2] * _billboardTransform.m[12] + viewMat.m[6] * _billboardTransform.m[13] + viewMat.m[10] * _billboardTransform.m[14] + viewMat.m[14]);
        _mvTransform = transform;
        _camWorldMat = camWorldMat;
    }

    //FIXME: frustum culling here
    {
        _quadCommand.init(_zDepthInView, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _billboardTransform);
        _quadCommand.setTransparent(true);
        renderer->addCommand(&_quadCommand);
    }
}
Example #23
0
Mat4 Node::getWorldToNodeTransform() const
{
    return getNodeToWorldTransform().getInversed();
}
Example #24
0
void PUParticle3DBoxRender::render( Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem )
{
    //batch and generate draw
    const ParticlePool &particlePool = particleSystem->getParticlePool();
    if (!_isVisible || particlePool.empty())
        return;

    auto camera = Camera::getVisitingCamera();
    auto cameraMat = camera->getNodeToWorldTransform();
    Vec3 backward(cameraMat.m[8], cameraMat.m[9], cameraMat.m[10]);

    if (_vertexBuffer == nullptr && _indexBuffer == nullptr) {
        GLsizei stride = sizeof(VertexInfo);
        _vertexBuffer = VertexBuffer::create(stride, 8 * particleSystem->getParticleQuota());
        if (_vertexBuffer == nullptr)
        {
            CCLOG("PUParticle3DBoxRender::render create vertex buffer failed");
            return;
        }
        _vertexBuffer->retain();
        _vertices.resize(8 * particleSystem->getParticleQuota());

        _indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, 36 * particleSystem->getParticleQuota());
        if (_indexBuffer == nullptr)
        {
            CCLOG("PUParticle3DBoxRender::render create index buffer failed");
            return;
        }
        _indexBuffer->retain();
        _indices.resize(36 * particleSystem->getParticleQuota());
        reBuildIndices(particleSystem->getParticleQuota());
    }

    unsigned int vertexindex = 0;
    unsigned int index = 0;
    Mat4 texRot;
    Vec3 val;
    for (auto iter : particlePool.getActiveDataList())
    {
        auto particle = static_cast<PUParticle3D *>(iter);
        float halfHeight = particle->height * 0.5f;
        float halfWidth = particle->width * 0.5f;
        float halfDepth = particle->depth * 0.5f;
        Mat4::createRotation(backward, particle->zRotation, &texRot);
        val = texRot * Vec3(0.0f, 0.75f, 0.0);
        _vertices[vertexindex + 0].position = particle->position + Vec3(-halfWidth, -halfHeight, halfDepth);
        _vertices[vertexindex + 0].color = particle->color;
        _vertices[vertexindex + 0].uv.x = val.x;
        _vertices[vertexindex + 0].uv.y = val.y;
        val = texRot * Vec3(0.0f, 0.25f, 0.0);
        _vertices[vertexindex + 1].position = particle->position + Vec3(halfWidth, -halfHeight, halfDepth);
        _vertices[vertexindex + 1].color = particle->color;
        _vertices[vertexindex + 1].uv.x = val.x;
        _vertices[vertexindex + 1].uv.y = val.y;
        val = texRot * Vec3(0.5f, 0.25f, 0.0);
        _vertices[vertexindex + 2].position = particle->position + Vec3(halfWidth, halfHeight, halfDepth);
        _vertices[vertexindex + 2].color = particle->color;
        _vertices[vertexindex + 2].uv.x = val.x;
        _vertices[vertexindex + 2].uv.y = val.y;
        val = texRot * Vec3(0.5f, 0.75f, 0.0);
        _vertices[vertexindex + 3].position = particle->position + Vec3(-halfWidth, halfHeight, halfDepth);
        _vertices[vertexindex + 3].color = particle->color;
        _vertices[vertexindex + 3].uv.x = val.x;
        _vertices[vertexindex + 3].uv.y = val.y;

        val = texRot * Vec3(0.0f, 0.0f, 0.0);
        _vertices[vertexindex + 4].position = particle->position + Vec3(halfWidth, -halfHeight, -halfDepth);
        _vertices[vertexindex + 4].color = particle->color;
        _vertices[vertexindex + 4].uv.x = val.x;
        _vertices[vertexindex + 4].uv.y = val.y;
        val = texRot * Vec3(0.0f, 1.0f, 0.0);
        _vertices[vertexindex + 5].position = particle->position + Vec3(-halfWidth, -halfHeight, -halfDepth);
        _vertices[vertexindex + 5].color = particle->color;
        _vertices[vertexindex + 5].uv.x = val.x;
        _vertices[vertexindex + 5].uv.y = val.y;
        val = texRot * Vec3(0.5f, 1.0f, 0.0);
        _vertices[vertexindex + 6].position = particle->position + Vec3(-halfWidth, halfHeight, -halfDepth);
        _vertices[vertexindex + 6].color = particle->color;
        _vertices[vertexindex + 6].uv.x = val.x;
        _vertices[vertexindex + 6].uv.y = val.y;
        val = texRot * Vec3(0.5f, 0.0f, 0.0);
        _vertices[vertexindex + 7].position = particle->position + Vec3(halfWidth, halfHeight, -halfDepth);
        _vertices[vertexindex + 7].color = particle->color;
        _vertices[vertexindex + 7].uv.x = val.x;
        _vertices[vertexindex + 7].uv.y = val.y;

        vertexindex += 8;
        index += 36;
    }

    if (!_vertices.empty() && !_indices.empty()) {
        _vertexBuffer->updateVertices(&_vertices[0], vertexindex/* * sizeof(_posuvcolors[0])*/, 0);
        _indexBuffer->updateIndices(&_indices[0], index/* * sizeof(unsigned short)*/, 0);

        GLuint texId = (_texture ? _texture->getName() : 0);
        _stateBlock->setBlendFunc(_particleSystem->getBlendFunc());
        _meshCommand->init(0,
                           texId,
                           _glProgramState,
                           _stateBlock,
                           _vertexBuffer->getVBO(),
                           _indexBuffer->getVBO(),
                           GL_TRIANGLES,
                           GL_UNSIGNED_SHORT,
                           index,
                           transform,
                           Node::FLAGS_RENDER_AS_3D);
        _meshCommand->setSkipBatching(true);
        _meshCommand->setTransparent(true);

        _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1));
        renderer->addCommand(_meshCommand);
    }
}
void MeshCommand::setLightUniforms()
{
    Director *director = Director::getInstance();
    auto scene = director->getRunningScene();
    const auto& conf = Configuration::getInstance();
    int maxDirLight = conf->getMaxSupportDirLightInShader();
    int maxPointLight = conf->getMaxSupportPointLightInShader();
    int maxSpotLight = conf->getMaxSupportSpotLightInShader();
    auto &lights = scene->getLights();
    auto glProgram = _glProgramState->getGLProgram();
    if (_glProgramState->getVertexAttribsFlags() & (1 << GLProgram::VERTEX_ATTRIB_NORMAL))
    {
        resetLightUniformValues();

        GLint enabledDirLightNum = 0;
        GLint enabledPointLightNum = 0;
        GLint enabledSpotLightNum = 0;
        Vec3 ambientColor;
        for (const auto& light : lights)
        {
            bool useLight = light->isEnabled() && ((unsigned int)light->getLightFlag() & _lightMask);
            if (useLight)
            {
                float intensity = light->getIntensity();
                switch (light->getLightType())
                {
                    case LightType::DIRECTIONAL:
                    {
                        if(enabledDirLightNum < maxDirLight)
                        {
                            auto dirLight = static_cast<DirectionLight *>(light);
                            Vec3 dir = dirLight->getDirectionInWorld();
                            dir.normalize();
                            const Color3B &col = dirLight->getDisplayedColor();
                            s_dirLightUniformColorValues[enabledDirLightNum] = Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
                            s_dirLightUniformDirValues[enabledDirLightNum] = dir;
                            ++enabledDirLightNum;
                        }
                        
                    }
                        break;
                    case LightType::POINT:
                    {
                        if(enabledPointLightNum < maxPointLight)
                        {
                            auto pointLight = static_cast<PointLight *>(light);
                            Mat4 mat= pointLight->getNodeToWorldTransform();
                            const Color3B &col = pointLight->getDisplayedColor();
                            s_pointLightUniformColorValues[enabledPointLightNum] = Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
                            s_pointLightUniformPositionValues[enabledPointLightNum] = Vec3(mat.m[12], mat.m[13], mat.m[14]);
                            s_pointLightUniformRangeInverseValues[enabledPointLightNum] = 1.0f / pointLight->getRange();
                            ++enabledPointLightNum;
                        }
                    }
                        break;
                    case LightType::SPOT:
                    {
                        if(enabledSpotLightNum < maxSpotLight)
                        {
                            auto spotLight = static_cast<SpotLight *>(light);
                            Vec3 dir = spotLight->getDirectionInWorld();
                            dir.normalize();
                            Mat4 mat= light->getNodeToWorldTransform();
                            const Color3B &col = spotLight->getDisplayedColor();
                            s_spotLightUniformColorValues[enabledSpotLightNum] = Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
                            s_spotLightUniformPositionValues[enabledSpotLightNum] = Vec3(mat.m[12], mat.m[13], mat.m[14]);
                            s_spotLightUniformDirValues[enabledSpotLightNum] = dir;
                            s_spotLightUniformInnerAngleCosValues[enabledSpotLightNum] = spotLight->getCosInnerAngle();
                            s_spotLightUniformOuterAngleCosValues[enabledSpotLightNum] = spotLight->getCosOuterAngle();
                            s_spotLightUniformRangeInverseValues[enabledSpotLightNum] = 1.0f / spotLight->getRange();
                            ++enabledSpotLightNum;
                        }
                    }
                        break;
                    case LightType::AMBIENT:
                    {
                        auto ambLight = static_cast<AmbientLight *>(light);
                        const Color3B &col = ambLight->getDisplayedColor();
                        ambientColor += Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
                    }
                        break;
                    default:
                        break;
                }
            }
        }
        
        if (0 < maxDirLight)
        {
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_dirLightUniformColorName), (GLfloat*)(&s_dirLightUniformColorValues[0]), (unsigned int)s_dirLightUniformColorValues.size());
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_dirLightUniformDirName), (GLfloat*)(&s_dirLightUniformDirValues[0]), (unsigned int)s_dirLightUniformDirValues.size());
        }

        if (0 < maxPointLight)
        {
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_pointLightUniformColorName), (GLfloat*)(&s_pointLightUniformColorValues[0]), (unsigned int)s_pointLightUniformColorValues.size());
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_pointLightUniformPositionName), (GLfloat*)(&s_pointLightUniformPositionValues[0]), (unsigned int)s_pointLightUniformPositionValues.size());
            glProgram->setUniformLocationWith1fv((GLint)glProgram->getUniformLocationForName(s_pointLightUniformRangeInverseName), (GLfloat*)(&s_pointLightUniformRangeInverseValues[0]), (unsigned int)s_pointLightUniformRangeInverseValues.size());
        }

        if (0 < maxSpotLight)
        {
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformColorName), (GLfloat*)(&s_spotLightUniformColorValues[0]), (unsigned int)s_spotLightUniformColorValues.size());
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformPositionName), (GLfloat*)(&s_spotLightUniformPositionValues[0]), (unsigned int)s_spotLightUniformPositionValues.size());
            glProgram->setUniformLocationWith3fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformDirName), (GLfloat*)(&s_spotLightUniformDirValues[0]), (unsigned int)s_spotLightUniformDirValues.size());
            glProgram->setUniformLocationWith1fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformInnerAngleCosName), (GLfloat*)(&s_spotLightUniformInnerAngleCosValues[0]), (unsigned int)s_spotLightUniformInnerAngleCosValues.size());
            glProgram->setUniformLocationWith1fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformOuterAngleCosName), (GLfloat*)(&s_spotLightUniformOuterAngleCosValues[0]), (unsigned int)s_spotLightUniformOuterAngleCosValues.size());
            glProgram->setUniformLocationWith1fv((GLint)glProgram->getUniformLocationForName(s_spotLightUniformRangeInverseName), (GLfloat*)(&s_spotLightUniformRangeInverseValues[0]), (unsigned int)s_spotLightUniformRangeInverseValues.size());
        }

        glProgram->setUniformLocationWith3f(glProgram->getUniformLocationForName(s_ambientLightUniformColorName), ambientColor.x, ambientColor.y, ambientColor.z);
    }
    else // normal does not exist
    {
        Vec3 ambient(0.0f, 0.0f, 0.0f);
        bool hasAmbient;
        for (const auto& light : lights)
        {
            if (light->getLightType() == LightType::AMBIENT)
            {
                bool useLight = light->isEnabled() && ((unsigned int)light->getLightFlag() & _lightMask);
                if (useLight)
                {
                    hasAmbient = true;
                    const Color3B &col = light->getDisplayedColor();
                    ambient.x += col.r * light->getIntensity();
                    ambient.y += col.g * light->getIntensity();
                    ambient.z += col.b * light->getIntensity();
                }
            }
        }
        if (hasAmbient)
        {
            ambient.x /= 255.f; ambient.y /= 255.f; ambient.z /= 255.f;
        }
        glProgram->setUniformLocationWith4f(glProgram->getUniformLocationForName("u_color"), _displayColor.x * ambient.x, _displayColor.y * ambient.y, _displayColor.z * ambient.z, _displayColor.w);
    }
}
Example #26
0
void PUParticle3DQuadRender::render(Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem)
{
    //batch and generate draw
    const ParticlePool &particlePool = particleSystem->getParticlePool();
    if (!_isVisible || particlePool.empty())
        return;

    if (_vertexBuffer == nullptr) {
        GLsizei stride = sizeof(VertexInfo);
        _vertexBuffer = VertexBuffer::create(stride, 4 * particleSystem->getParticleQuota());
        if (_vertexBuffer == nullptr)
        {
            CCLOG("PUParticle3DQuadRender::render create vertex buffer failed");
            return;
        }
        _vertexBuffer->retain();
    }

    if (_indexBuffer == nullptr) {
        _indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, 6 * particleSystem->getParticleQuota());
        if (_indexBuffer == nullptr)
        {
            CCLOG("PUParticle3DQuadRender::render create index buffer failed");
            return;
        }
        _indexBuffer->retain();
    }
    const ParticlePool::PoolList &activeParticleList = particlePool.getActiveDataList();
    if (_vertices.size() < activeParticleList.size() * 4)
    {
        _vertices.resize(activeParticleList.size() * 4);
        _indices.resize(activeParticleList.size() * 6);
    }

    auto camera = Camera::getVisitingCamera();
    auto cameraMat = camera->getNodeToWorldTransform();


    //for (auto iter : activeParticleList){
    //    iter->depthInView = -(viewMat.m[2] * iter->positionInWorld.x + viewMat.m[6] * iter->positionInWorld.y + viewMat.m[10] * iter->positionInWorld.z + viewMat.m[14]);
    //}

    //std::sort(activeParticleList.begin(), activeParticleList.end(), compareParticle3D);
    Vec3 right(cameraMat.m[0], cameraMat.m[1], cameraMat.m[2]);
    Vec3 up(cameraMat.m[4], cameraMat.m[5], cameraMat.m[6]);
    Vec3 backward(cameraMat.m[8], cameraMat.m[9], cameraMat.m[10]);

    Mat4 pRotMat;
    Vec3 position; //particle position
    int vertexindex = 0;
    int index = 0;
    int offsetX,offsetY;
    getOriginOffset(offsetX, offsetY);

    if (_type == PERPENDICULAR_COMMON) {
        up = _commonUp;
        up.normalize();
        Vec3::cross(up, _commonDir, &right);
        right.normalize();
        backward = _commonDir;
    } else if (_type == ORIENTED_COMMON) {
        up = _commonDir;
        up.normalize();
        Vec3::cross(up, backward, &right);
        right.normalize();
    }

    for (auto iter : activeParticleList)
    {
        auto particle = static_cast<PUParticle3D *>(iter);
        determineUVCoords(particle);
        if (_type == ORIENTED_SELF) {
            Vec3 direction = particle->direction;
            //transform.transformVector(particle->direction, &direction);
            up = direction;
            up.normalize();
            Vec3::cross(direction, backward, &right);
            right.normalize();
        } else if (_type == PERPENDICULAR_SELF) {
            Vec3 direction = particle->direction;
            //transform.transformVector(particle->direction, &direction);
            direction.normalize();
            //up = PUUtil::perpendicular(direction);
            //up.normalize();
            Vec3::cross(_commonUp, direction, &right);
            right.normalize();
            Vec3::cross(direction, right, &up);
            up.normalize();
            backward = direction;
        } else if (_type == ORIENTED_SHAPE) {
            up.set(particle->orientation.x, particle->orientation.y, particle->orientation.z);
            up.normalize();
            Vec3::cross(up, backward, &right);
            right.normalize();
        }
        Vec3 halfwidth = particle->width * 0.5f * right;
        Vec3 halfheight = particle->height * 0.5f * up;
        Vec3 offset = halfwidth * offsetX + halfheight * offsetY;
        //transform.transformPoint(particle->position, &position);
        position = particle->position;

        if (_rotateType == TEXTURE_COORDS) {
            float costheta = cosf(-particle->zRotation);
            float sintheta = sinf(-particle->zRotation);
            Vec2 texOffset = 0.5f * (particle->lb_uv + particle->rt_uv);
            Vec2 val;
            val.set((particle->lb_uv.x - texOffset.x), (particle->lb_uv.y - texOffset.y));
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex, (position + (-halfwidth - halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->rt_uv.x - texOffset.x, particle->lb_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 1, (position + (halfwidth - halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->lb_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 2, (position + (-halfwidth + halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->rt_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 3, (position + (halfwidth + halfheight + offset)), particle->color, val + texOffset);
        } else {
            Mat4::createRotation(backward, -particle->zRotation, &pRotMat);
            fillVertex(vertexindex    , (position + pRotMat * (- halfwidth - halfheight + offset)), particle->color, particle->lb_uv);
            fillVertex(vertexindex + 1, (position + pRotMat * (halfwidth - halfheight + offset)), particle->color, Vec2(particle->rt_uv.x, particle->lb_uv.y));
            fillVertex(vertexindex + 2, (position + pRotMat * (-halfwidth + halfheight + offset)), particle->color, Vec2(particle->lb_uv.x, particle->rt_uv.y));
            fillVertex(vertexindex + 3, (position + pRotMat * (halfwidth + halfheight + offset)), particle->color, particle->rt_uv);
        }

        fillTriangle(index, vertexindex, vertexindex + 1, vertexindex + 3);
        fillTriangle(index + 3, vertexindex, vertexindex + 3, vertexindex + 2);

        //_posuvcolors[vertexindex].position = (position + (- halfwidth - halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex].color = particle->color;
        //_posuvcolors[vertexindex].uv.set(val.x + texOffset.x, val.y + texOffset.y);

        //val.set(particle->rt_uv.x - texOffset.x, particle->lb_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 1].position = (position + (halfwidth - halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 1].color = particle->color;
        //_posuvcolors[vertexindex + 1].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //val.set(particle->lb_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 2].position = (position + (- halfwidth + halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 2].color = particle->color;
        //_posuvcolors[vertexindex + 2].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //val.set(particle->rt_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 3].position = (position + (halfwidth + halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 3].color = particle->color;
        //_posuvcolors[vertexindex + 3].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //
        //_indexData[index] = vertexindex;
        //_indexData[index + 1] = vertexindex + 1;
        //_indexData[index + 2] = vertexindex + 3;
        //_indexData[index + 3] = vertexindex;
        //_indexData[index + 4] = vertexindex + 3;
        //_indexData[index + 5] = vertexindex + 2;

        index += 6;
        vertexindex += 4;

    }

    _vertices.erase(_vertices.begin() + vertexindex, _vertices.end());
    _indices.erase(_indices.begin() + index, _indices.end());

    if (!_vertices.empty() && !_indices.empty()) {
        _vertexBuffer->updateVertices(&_vertices[0], vertexindex/* * sizeof(_posuvcolors[0])*/, 0);
        _indexBuffer->updateIndices(&_indices[0], index/* * sizeof(unsigned short)*/, 0);

        _stateBlock->setBlendFunc(particleSystem->getBlendFunc());

        GLuint texId = (_texture ? _texture->getName() : 0);
        _meshCommand->init(0,
                           texId,
                           _glProgramState,
                           _stateBlock,
                           _vertexBuffer->getVBO(),
                           _indexBuffer->getVBO(),
                           GL_TRIANGLES,
                           GL_UNSIGNED_SHORT,
                           index,
                           transform,
                           Node::FLAGS_RENDER_AS_3D);
        _meshCommand->setSkipBatching(true);
        _meshCommand->setTransparent(true);
        _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1));
        renderer->addCommand(_meshCommand);
    }
}
Example #27
0
Vec3 DirectionLight::getDirectionInWorld() const
{
    Mat4 mat = getNodeToWorldTransform();
    return Vec3(-mat.m[8], -mat.m[9], -mat.m[10]);
}
Example #28
0
bool BillBoard::calculateBillbaordTransform()
{
    //Get camera world position
    auto camera = Camera::getVisitingCamera();
    const Mat4& camWorldMat = camera->getNodeToWorldTransform();
    
    //TODO: use math lib to calculate math lib Make it easier to read and maintain
    if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_mvTransform.m, _modelViewTransform.m, sizeof(float) * 16) != 0 || _modeDirty || true)
    {
        //Rotate based on anchor point
        Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f);
        Mat4 localToWorld = _modelViewTransform;
        localToWorld.translate(anchorPoint);
        
        //Decide billboard mode
        Vec3 camDir;
        switch (_mode)
        {
            case Mode::VIEW_POINT_ORIENTED:
                camDir.set(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]);
                break;
            case Mode::VIEW_PLANE_ORIENTED:
                camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
                break;
            default:
                CCASSERT(false, "invalid billboard mode");
                break;
        }
        _modeDirty = false;
        
        if (camDir.length() < MATH_TOLERANCE)
        {
            camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
        }
        camDir.normalize();
        
        Quaternion rotationQuaternion;
        this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
        
        Mat4 rotationMatrix;
        rotationMatrix.setIdentity();

        Vec3 upAxis(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
        Vec3 x, y;
        camWorldMat.transformVector(upAxis, &y);
        Vec3::cross(camDir, y, &x);
        x.normalize();
        Vec3::cross(x, camDir, &y);
        y.normalize();
        
        float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]);
        float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]);
        float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.m[10]);
        
        Mat4 billboardTransform;
        
        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] = localToWorld.m[12]; billboardTransform.m[13] = localToWorld.m[13]; billboardTransform.m[14] = localToWorld.m[14];
        
        billboardTransform.translate(-anchorPoint);
        _mvTransform = _modelViewTransform = billboardTransform;
        
        _camWorldMat = camWorldMat;
        
        return true;
    }
    
    return false;
}