void OrbitCamera::update(fzFloat dt) { fzFloat r = (m_radius + m_deltaRadius * dt) * Camera::defaultEyeZ; fzFloat za = m_radZ + m_radDeltaZ * dt; fzFloat xa = m_radX + m_radDeltaX * dt; fzFloat zaSin = fzMath_sin(za); fzPoint3 eye(zaSin * fzMath_cos(xa) * r + m_centerOrig.x, zaSin * fzMath_sin(xa) * r + m_centerOrig.y, fzMath_cos(za) * r + m_centerOrig.z); // Update camera values ((Node*)p_target)->getCamera()->setEye(eye); }
void fzMath_mat4PerspectiveProjection(fzFloat fovY, fzFloat aspect, fzFloat zNear, fzFloat zFar, float *output) { FZ_ASSERT(output != NULL, "Output matrix cannot be NULL."); fzFloat r = FZ_DEGREES_TO_RADIANS(fovY / 2); fzFloat deltaZ = zFar - zNear; fzFloat s = fzMath_sin(r); fzFloat cotangent = 0; if (deltaZ == 0 || s == 0 || aspect == 0) { FZLOGERROR("Perpertive impossible."); return; } cotangent = fzMath_cos(r) / s; fzMath_mat4Identity(output); output[0] = cotangent / aspect; output[5] = cotangent; output[10] = -(zFar + zNear) / deltaZ; output[11] = -1; output[14] = -2 * zNear * zFar / deltaZ; output[15] = 0; }
void fzDrawCircle( const fzVec2& center, fzFloat r, fzFloat a, fzUInt segs, bool drawLineToCenter) { int additionalSegment = 1; if (drawLineToCenter) additionalSegment++; const float coef = 2.0f * (float)M_PI/segs; fzVec2 *vertices = new fzVec2[segs+2]; for(fzUInt i = 0; i <= segs; i++) { float rads = i * coef; GLfloat j = r * fzMath_cos(rads + a) + center.x; GLfloat k = r * fzMath_sin(rads + a) + center.y; vertices[i] = fzPoint(j, k); } vertices[segs+1] = center; fzGLSetMode(kFZGLMode_Primitives); #if FZ_GL_SHADERS lazyInitialize(); _fzShader->use(); FZ_SAFE_APPLY_MATRIX(_fzShader); glVertexAttribPointer(kFZAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, vertices); #else glVertexPointer(2, GL_FLOAT, 0, vertices); #endif glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segs+additionalSegment); delete [] vertices; }
void ParticleSystem::update(fzFloat dt) { if( m_isActive && m_emissionRate ) { fzFloat rate = 1.0f / m_emissionRate; m_emitCounter += dt; while( m_particleCount < m_totalParticles && m_emitCounter > rate ) { addParticle(); m_emitCounter -= rate; } m_elapsed += dt; if(m_duration != -1 && m_duration < m_elapsed) stopSystem(); } m_particleIdx = 0; while( m_particleIdx < m_particleCount ) { fzParticle& p = p_particles[m_particleIdx]; // life p.timeToLive -= dt; if( p.timeToLive > 0 ) { // Mode A if( m_emitterMode == kFZParticleModeGravity ) { fzPoint tmp(p.pos); if(tmp != FZPointZero) { // calculate tangential fzPoint tangential(tmp.getPerp()); tangential.normalize(); tangential *= p.mode.A.tangentialAccel; // radial acceleration tmp *= p.mode.A.radialAccel; // radial + tangential tmp += tangential; } // (gravity + dir + radial + tangential) * dt tmp += mode.A.gravity; tmp += p.mode.A.dir; p.pos += tmp * dt; } // Mode B else { // Update the angle and radius of the particle. p.mode.B.angle += p.mode.B.degreesPerSecond * dt; p.mode.B.radius += p.mode.B.deltaRadius * dt; p.pos.x = -fzMath_cos(p.mode.B.angle) * p.mode.B.radius; p.pos.y = -fzMath_sin(p.mode.B.angle) * p.mode.B.radius; } // color p.color += p.deltaColor * dt; // size p.size += p.deltaSize * dt; p.size = p.size < 0 ? 0 : p.size; // angle p.rotation += p.deltaRotation * dt; // update values in quad updateQuadWithParticle(p); // update particle counter ++m_particleIdx; } else { // life < 0 --m_particleCount; if( m_particleIdx != m_particleCount ) memmove(&p_particles[m_particleIdx], &p_particles[m_particleCount], sizeof(fzParticle)); if( m_particleCount == 0 && m_autoRemoveOnFinish ) { unschedule(); removeFromParent(true); return; } } } if(m_particleCount) makeDirty(0); #if FZ_VBO_STREAMING postStep(); #endif }
void ParticleSystem::initParticle(fzParticle& particle) { // time to live particle.timeToLive = m_life + m_lifeVar * FZ_RANDOM_MINUS1_1(); if(particle.timeToLive < 0) particle.timeToLive = 0; // position particle.pos = m_sourcePosition + m_posVar * FZ_RANDOM_MINUS1_1(); // color fzColor4F start(m_startColor.r + m_startColorVar.r * FZ_RANDOM_MINUS1_1(), m_startColor.g + m_startColorVar.g * FZ_RANDOM_MINUS1_1(), m_startColor.b + m_startColorVar.b * FZ_RANDOM_MINUS1_1(), m_startColor.a + m_startColorVar.a * FZ_RANDOM_MINUS1_1()); fzColor4F end(m_endColor.r + m_endColorVar.r * FZ_RANDOM_MINUS1_1(), m_endColor.g + m_endColorVar.g * FZ_RANDOM_MINUS1_1(), m_endColor.b + m_endColorVar.b * FZ_RANDOM_MINUS1_1(), m_endColor.a + m_endColorVar.a * FZ_RANDOM_MINUS1_1()); particle.color = start; particle.deltaColor = (end - start) * (1 / particle.timeToLive); // size fzFloat startS = m_startSize + m_startSizeVar * FZ_RANDOM_MINUS1_1(); if(startS < 0) startS = 0; particle.size = startS; if( m_endSize == kFZParticleStartSizeEqualToEndSize ) particle.deltaSize = 0; else { fzFloat endS = m_endSize + m_endSizeVar * FZ_RANDOM_MINUS1_1(); if(endS < 0) endS = 0; particle.deltaSize = (endS - startS) / particle.timeToLive; } // rotation fzFloat startA = m_startSpin + m_startSpinVar * FZ_RANDOM_MINUS1_1(); fzFloat endA = m_endSpin + m_endSpinVar * FZ_RANDOM_MINUS1_1(); particle.rotation = startA; particle.deltaRotation = (endA - startA) / particle.timeToLive; // direction fzFloat a = FZ_DEGREES_TO_RADIANS( m_angle + m_angleVar * FZ_RANDOM_MINUS1_1() ); // Mode Gravity: A if( m_emitterMode == kFZParticleModeGravity ) { fzFloat s = mode.A.speed + mode.A.speedVar * FZ_RANDOM_MINUS1_1(); // direction particle.mode.A.dir.x = fzMath_cos(a) * s; particle.mode.A.dir.y = fzMath_sin(a) * s; // radial accel particle.mode.A.radialAccel = mode.A.radialAccel + mode.A.radialAccelVar * FZ_RANDOM_MINUS1_1(); // tangential accel particle.mode.A.tangentialAccel = mode.A.tangentialAccel + mode.A.tangentialAccelVar * FZ_RANDOM_MINUS1_1(); } // Mode Radius: B else { // Set the default diameter of the particle from the source position fzFloat startRadius = mode.B.startRadius + mode.B.startRadiusVar * FZ_RANDOM_MINUS1_1(); fzFloat endRadius = mode.B.endRadius + mode.B.endRadiusVar * FZ_RANDOM_MINUS1_1(); particle.mode.B.radius = startRadius; particle.mode.B.deltaRadius = (mode.B.endRadius == kFZParticleStartRadiusEqualToEndRadius) ? 0 : ((endRadius- startRadius) / particle.timeToLive); particle.mode.B.angle = a; particle.mode.B.degreesPerSecond = FZ_DEGREES_TO_RADIANS(mode.B.rotatePerSecond + mode.B.rotatePerSecondVar * FZ_RANDOM_MINUS1_1()); } }
void ParticleSystemQuad::updateQuadWithParticle(const fzParticle& p) { // colors fzC4_T2_V2_Quad& quad = p_quads[m_particleIdx]; fzColor4B color4B(p.color); quad.bl.color = color4B; quad.br.color = color4B; quad.tl.color = color4B; quad.tr.color = color4B; // vertices fzFloat size_2 = p.size/2; if( p.rotation ) { fzFloat x1 = -size_2; fzFloat y1 = -size_2; fzFloat& x2 = size_2; fzFloat& y2 = size_2; const fzFloat& x = p.pos.x; const fzFloat& y = p.pos.y; fzFloat r = -FZ_DEGREES_TO_RADIANS(p.rotation); fzFloat sr = fzMath_sin(r); fzFloat cr = fzMath_cos(r); fzFloat ax = x1 * cr - y1 * sr + x; fzFloat ay = x1 * sr + y1 * cr + y; fzFloat bx = x2 * cr - y1 * sr + x; fzFloat by = x2 * sr + y1 * cr + y; fzFloat cx = x2 * cr - y2 * sr + x; fzFloat cy = x2 * sr + y2 * cr + y; fzFloat dx = x1 * cr - y2 * sr + x; fzFloat dy = x1 * sr + y2 * cr + y; // bottom-left quad.bl.vertex.x = ax; quad.bl.vertex.y = ay; // bottom-right vertex: quad.br.vertex.x = bx; quad.br.vertex.y = by; // top-left vertex: quad.tl.vertex.x = dx; quad.tl.vertex.y = dy; // top-right vertex: quad.tr.vertex.x = cx; quad.tr.vertex.y = cy; } else { // bottom-left vertex: quad.bl.vertex.x = p.pos.x - size_2; quad.bl.vertex.y = p.pos.y - size_2; // bottom-right vertex: quad.br.vertex.x = p.pos.x + size_2; quad.br.vertex.y = p.pos.y - size_2; // top-left vertex: quad.tl.vertex.x = p.pos.x - size_2; quad.tl.vertex.y = p.pos.y + size_2; // top-right vertex: quad.tr.vertex.x = p.pos.x + size_2; quad.tr.vertex.y = p.pos.y + size_2; } }