void ARX_PARTICLES_Update(EERIE_CAMERA * cam) { ARX_PROFILE_FUNC(); if(!ACTIVEBKG) { return; } if(ParticleCount == 0) { return; } const ArxInstant now = arxtime.now(); long pcc = ParticleCount; for(size_t i = 0; i < MAX_PARTICLES && pcc > 0; i++) { PARTICLE_DEF * part = &particle[i]; if(!part->exist) { continue; } long framediff = part->timcreation + part->tolive - now; long framediff2 = now - part->timcreation; if(framediff2 < long(part->delay)) { continue; } if(part->delay > 0) { part->timcreation += part->delay; part->delay=0; if((part->m_flags & DELAY_FOLLOW_SOURCE) && part->sourceionum != EntityHandle() && entities[part->sourceionum]) { part->ov = *part->source; Entity * target = entities[part->sourceionum]; Vec3f vector = (part->ov - target->pos) * Vec3f(1.f, 0.5f, 1.f); vector = glm::normalize(vector); part->move = vector * Vec3f(18.f, 5.f, 18.f) + randomVec(-0.5f, 0.5f); } continue; } if(!part->is2D) { EERIE_BKG_INFO * bkgData = getFastBackgroundData(part->ov.x, part->ov.z); if(!bkgData || !bkgData->treat) { part->exist = false; ParticleCount--; continue; } } if(framediff <= 0) { if((part->m_flags & FIRE_TO_SMOKE) && Random::getf() > 0.7f) { part->ov += part->move; part->tolive = part->tolive * 1.375f; part->m_flags &= ~FIRE_TO_SMOKE; part->tc = smokeparticle; part->scale = glm::abs(part->scale * 2.4f); part->rgb = Color3f::gray(.45f); part->move *= 0.5f; part->siz *= 1.f / 3; part->timcreation = now; framediff = part->tolive; } else { part->exist = false; ParticleCount--; continue; } } float val = (part->tolive - framediff) * 0.01f; Vec3f in = part->ov + part->move * val; Vec3f inn = in; if(part->m_flags & GRAVITY) { in.y = inn.y = inn.y + 1.47f * val * val; } float fd = float(framediff2) / float(part->tolive); float r = 1.f - fd; if(part->m_flags & FADE_IN_AND_OUT) { long t = part->tolive / 2; if(framediff2 <= t) { r = float(framediff2) / float(t); } else { r = 1.f - float(framediff2 - t) / float(t); } } if(!part->is2D) { Sphere sp; sp.origin = in; TexturedVertex out; EE_RTP(inn, out); if(out.rhw < 0 || out.p.z > cam->cdepth * fZFogEnd) { continue; } if(part->m_flags & SPLAT_GROUND) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * 10.f; if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb; PolyBoomAddSplat(sp, rgb, 0); } part->exist = false; ParticleCount--; continue; } } if(part->m_flags & SPLAT_WATER) { float siz = part->siz + part->scale.x * fd; sp.radius = siz * Random::getf(10.f, 30.f); if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) { if(Random::getf() < 0.9f) { Color3f rgb = part->rgb * 0.5f; PolyBoomAddSplat(sp, rgb, 2); } part->exist = false; ParticleCount--; continue; } } if((part->m_flags & DISSIPATING) && out.p.z < 0.05f) { out.p.z *= 20.f; r *= out.p.z; } } if(r <= 0.f) { pcc--; continue; } if(part->m_flags & PARTICLE_GOLDRAIN) { float v = Random::getf(-0.1f, 0.1f); if(part->rgb.r + v <= 1.f && part->rgb.r + v > 0.f && part->rgb.g + v <= 1.f && part->rgb.g + v > 0.f && part->rgb.b + v <= 1.f && part->rgb.b + v > 0.f) { part->rgb = Color3f(part->rgb.r + v, part->rgb.g + v, part->rgb.b + v); } } Color color = (part->rgb * r).to<u8>(); if(player.m_improve) { color.g = 0; } TextureContainer * tc = part->tc; if(tc == explo[0] && (part->m_flags & PARTICLE_ANIMATED)) { long animrange = part->cval2 - part->cval1; long num = long(float(framediff2) / float(part->tolive) * animrange); num = glm::clamp(num, long(part->cval1), long(part->cval2)); tc = explo[num]; } float siz = part->siz + part->scale.x * fd; RenderMaterial mat; mat.setTexture(tc); mat.setDepthTest(!(part->m_flags & PARTICLE_NOZBUFFER)); if(part->m_flags & PARTICLE_SUB2) { mat.setBlendType(RenderMaterial::Subtractive2); color.a = glm::clamp(r * 1.5f, 0.f, 1.f) * 255; } else if(part->m_flags & SUBSTRACT) { mat.setBlendType(RenderMaterial::Subtractive); } else { mat.setBlendType(RenderMaterial::Additive); } if(part->m_flags & ROTATING) { if(!part->is2D) { float rott = MAKEANGLE(float(now + framediff2) * part->m_rotation); float temp = (part->zdec) ? 0.0001f : 2.f; float size = std::max(siz, 0.f); EERIEAddSprite(mat, in, size, color, temp, rott); } } else if(part->is2D) { float siz2 = part->siz + part->scale.y * fd; EERIEAddBitmap(mat, in, siz, siz2, tc, color); } else { float temp = (part->zdec) ? 0.0001f : 2.f; EERIEAddSprite(mat, in, siz, color, temp); } pcc--; } }
// TODO copy-paste spell effect Fissure void CSummonCreature::RenderFissure() { int i; float ff; Vec3f vt[4]; TexturedVertex vr[4]; Vec3f target; Vec3f etarget; etarget.x = fBetaRadCos; etarget.y = 0; etarget.z = fBetaRadSin; RenderMaterial mat; mat.setCulling(Renderer::CullNone); mat.setDepthTest(false); mat.setWrapMode(TextureStage::WrapClamp); mat.setBlendType(RenderMaterial::Opaque); mat.setLayer(RenderMaterial::EffectForeground); //------------------------------------------------------------------------- // computation des sommets for(i = 0; i <= std::min(end, int(fSizeIntro)); i++) { if(i <= end * 0.5f) ff = i / (end * 0.5f); else ff = 1.0f - ((i - (end + 1) * 0.5f) / (end * 0.5f)); float fTempCos = ff * fBetaRadCos; float fTempSin = ff * fBetaRadSin; va[i].x = v1a[i].x + sizeF * fTempCos; va[i].y = v1a[i].y; va[i].z = v1a[i].z + sizeF * fTempSin; vb[i].x = v1b[i].x - sizeF * fTempCos; vb[i].y = v1b[i].y; vb[i].z = v1b[i].z - sizeF * fTempSin; va[i].x += rnd() * 0.5f * fTempCos; va[i].z += rnd() * 0.5f * fTempSin; vb[i].x -= rnd() * 0.5f * fTempCos; vb[i].z -= rnd() * 0.5f * fTempSin; } //------------------------------------------------------------------------- // rendu de la fissure mat.setBlendType(RenderMaterial::Opaque); vr[0].color = vr[1].color = vr[2].color = vr[3].color = Color::black.toRGB(); if(bIntro) { for(i = 0; i < std::min(end, (int)fSizeIntro); i++) { vr[0].p = EE_RT(v1a[i]); vr[1].p = EE_RT(v1b[i]); vr[2].p = EE_RT(v1a[i+1]); vr[3].p = EE_RT(v1b[i+1]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } else { for(i = 0; i < std::min(end, (int)fSizeIntro); i++) { vr[0].p = EE_RT(va[i]); vr[1].p = EE_RT(vb[i]); vr[2].p = EE_RT(va[i+1]); vr[3].p = EE_RT(vb[i+1]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } //------------------------------------------------------------------------- // rendu de la bordure mat.setBlendType(RenderMaterial::Additive); vr[0].color = vr[1].color = Color::black.toRGB(); vr[2].color = vr[3].color = fColorBorder.toRGB(); for(i = 0; i < std::min(end, (int)fSizeIntro); i++) { vt[2] = va[i] - (va[i] - eSrc) * 0.2f; vt[3] = va[i + 1] - (va[i + 1] - eSrc) * 0.2f; vr[0].p = EE_RT(vt[3]); vr[1].p = EE_RT(vt[2]); vr[2].p = EE_RT(va[i+1]); vr[3].p = EE_RT(va[i]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); vt[2] = vb[i] - (vb[i] - eSrc) * 0.2f; vt[3] = vb[i + 1] - (vb[i + 1] - eSrc) * 0.2f; vr[3].p = EE_RT(vb[i]); vr[2].p = EE_RT(vb[i+1]); vr[1].p = EE_RT(vt[2]); vr[0].p = EE_RT(vt[3]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } //------------------------------------------------------------------------- // rendu des faisceaux // blend additif ou mul // smooth sur les cotés ou pas .. // texture sympa avec glow au milieu ou uv wrap mat.setWrapMode(TextureStage::WrapMirror); mat.setTexture(tex_light); target.x = eSrc.x + -fBetaRadSin * (1.5f * sizeF); target.y = eSrc.y; target.z = eSrc.z + fBetaRadCos * (1.5f * sizeF); EE_RTP(vt[1], &vr[0]); vr[0].color = vr[1].color = fColorRays1.toRGB(); vr[2].color = vr[3].color = fColorRays2.toRGB(); vr[0].uv.x = fTexWrap; vr[0].uv.y = 1; vr[1].uv.x = 1.0f + fTexWrap; vr[1].uv.y = 1; vr[2].uv.x = fTexWrap; vr[2].uv.y = 0; vr[3].uv.x = 1.0f + fTexWrap; vr[3].uv.y = 0; for(i = 0; i < end - 1; i++) { if(i < fSizeIntro) { vt[0] = va[i]; vt[1] = va[i + 1]; vt[2] = va[i] + (va[i] - target) * 2.f; vt[3] = va[i + 1] + (va[i + 1] - target) * 2.f; vr[0].color = (fColorRays1 * tfRaysa[i]).toRGB(); vr[1].color = (fColorRays1 * tfRaysa[i + 1]).toRGB(); vr[2].color = (fColorRays2 * tfRaysa[i]).toRGB(); vr[3].color = (fColorRays2 * tfRaysa[i + 1]).toRGB(); vr[3].p = EE_RT(vt[0]); vr[2].p = EE_RT(vt[1]); vr[1].p = EE_RT(vt[2]); vr[0].p = EE_RT(vt[3]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } if(i < fSizeIntro) { vt[0] = vb[i + 1]; vt[1] = vb[i]; vt[2] = vb[i + 1] + (vb[i + 1] - target) * 2.f; vt[3] = vb[i] + (vb[i] - target) * 2.f; vr[0].color = (fColorRays1 * tfRaysb[i]).toRGB(); vr[1].color = (fColorRays1 * tfRaysb[i + 1]).toRGB(); vr[2].color = (fColorRays2 * tfRaysb[i]).toRGB(); vr[3].color = (fColorRays2 * tfRaysb[i + 1]).toRGB(); vr[3].p = EE_RT(vt[0]); vr[2].p = EE_RT(vt[1]); vr[1].p = EE_RT(vt[2]); vr[0].p = EE_RT(vt[3]); drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } }
void ConfuseSpell::Update(float timeDelta) { ARX_UNUSED(timeDelta); Vec3f pos = entities[m_target]->pos; if(m_target != PlayerEntityHandle) { pos.y += entities[m_target]->physics.cyl.height - 30.f; } long idx = entities[m_target]->obj->fastaccess.head_group_origin; if(idx >= 0) { pos = entities[m_target]->obj->vertexlist3[idx].v; pos.y -= 50.f; } eCurPos = pos; RenderMaterial mat; mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); mat.setTexture(tex_trail); Anglef stiteangle = Anglef(0.f, -glm::degrees(arxtime.get_updated() * ( 1.0f / 500 )), 0.f); Draw3DObject(spapi, stiteangle, eCurPos, Vec3f_ONE, Color3f::white, mat); for(int i = 0; i < 6; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } Vec2f p = glm::diskRand(15.f); pd->ov = eCurPos + Vec3f(p.x, 0.f, p.y); pd->move = Vec3f(0.f, Random::getf(1.f, 4.f), 0.f); pd->siz = 0.25f; pd->tolive = Random::get(2300, 3300); pd->tc = tex_p1; pd->special = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; Color3f baseColor = Color3f(0.4f, 0.2f, 0.4f); Color3f randomFactor = Color3f(0.4f, 0.6f, 0.4f); Color3f c = baseColor + randomColor3f() * randomFactor; while(glm::abs(c.r - c.g) > 0.3f && glm::abs(c.g - c.b) > 0.3f) { c = baseColor + randomColor3f() * randomFactor; } pd->rgb = c * Color3f(0.8f, 0.8f, 0.8f); } if(!lightHandleIsValid(m_light)) m_light = GetFreeDynLight(); if(lightHandleIsValid(m_light)) { EERIE_LIGHT * light = lightHandleGet(m_light); light->intensity = 1.3f; light->fallstart = 180.f; light->fallend = 420.f; light->rgb = Color3f(0.3f, 0.3f, 0.5f) + Color3f(0.2f, 0.f, 0.2f) * randomColor3f(); light->pos = eCurPos; light->duration = 200; light->extras = 0; } }
void ConfuseSpell::Update() { Vec3f pos = entities[m_target]->pos; if(m_target != EntityHandle_Player) { pos.y += entities[m_target]->physics.cyl.height - 30.f; } ObjVertHandle idx = entities[m_target]->obj->fastaccess.head_group_origin; if(idx != ObjVertHandle()) { pos = entities[m_target]->obj->vertexlist3[idx.handleData()].v; pos.y -= 50.f; } eCurPos = pos; RenderMaterial mat; mat.setDepthTest(false); mat.setBlendType(RenderMaterial::Additive); mat.setTexture(tex_trail); Anglef stiteangle = Anglef(0.f, -glm::degrees(arxtime.now_f() * ( 1.0f / 500 )), 0.f); { AnimationDuration delta = AnimationDurationUs(s64(g_framedelay * 1000.f)); EERIEDrawAnimQuatUpdate(spapi, animlayer, stiteangle, eCurPos, delta, NULL, false); EERIEDrawAnimQuatRender(spapi, eCurPos, NULL, 0.f); } for(int i = 0; i < 6; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } Vec2f p = glm::diskRand(15.f); pd->ov = eCurPos + Vec3f(p.x, 0.f, p.y); pd->move = Vec3f(0.f, Random::getf(1.f, 4.f), 0.f); pd->siz = 0.25f; pd->tolive = Random::getu(2300, 3300); pd->tc = tex_p1; pd->m_flags = PARTICLE_GOLDRAIN | FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; Color3f baseColor = Color3f(0.4f, 0.2f, 0.4f); Color3f randomFactor = Color3f(0.4f, 0.6f, 0.4f); Color3f c = baseColor + randomColor3f() * randomFactor; while(glm::abs(c.r - c.g) > 0.3f && glm::abs(c.g - c.b) > 0.3f) { c = baseColor + randomColor3f() * randomFactor; } pd->rgb = c * Color3f(0.8f, 0.8f, 0.8f); } EERIE_LIGHT * light = dynLightCreate(m_light); if(light) { light->intensity = 1.3f; light->fallstart = 180.f; light->fallend = 420.f; light->rgb = Color3f(0.3f, 0.3f, 0.5f) + Color3f(0.2f, 0.f, 0.2f) * randomColor3f(); light->pos = eCurPos; light->duration = ArxDurationMs(200); light->extras = 0; } }
// TODO copy-paste spell effect Fissure void CRiseDead::RenderFissure() { float ff; Vec3f vt[4]; TexturedVertexUntransformed vr[4]; Vec3f target; RenderMaterial mat; mat.setCulling(CullNone); mat.setDepthTest(false); mat.setWrapMode(TextureStage::WrapClamp); mat.setBlendType(RenderMaterial::Opaque); mat.setLayer(RenderMaterial::EffectForeground); //------------------------------------------------------------------------- // computation des sommets for(int i = 0; i <= std::min(end, int(fSizeIntro)); i++) { if(i <= end * 0.5f) ff = i / (end * 0.5f); else ff = 1.0f - ((i - (end + 1) * 0.5f) / (end * 0.5f)); float fTempCos = ff * fBetaRadCos; float fTempSin = ff * fBetaRadSin; va[i].x = v1a[i].x + sizeF * fTempCos; va[i].y = v1a[i].y; va[i].z = v1a[i].z + sizeF * fTempSin; vb[i].x = v1b[i].x - sizeF * fTempCos; vb[i].y = v1b[i].y; vb[i].z = v1b[i].z - sizeF * fTempSin; va[i].x += Random::getf(0.f, 0.5f) * fTempCos; va[i].z += Random::getf(0.f, 0.5f) * fTempSin; vb[i].x -= Random::getf(0.f, 0.5f) * fTempCos; vb[i].z -= Random::getf(0.f, 0.5f) * fTempSin; } //------------------------------------------------------------------------- // rendu de la fissure mat.setBlendType(RenderMaterial::Opaque); vr[0].color = vr[1].color = vr[2].color = vr[3].color = Color::black.toRGB(); if(bIntro) { for(int i = 0; i < std::min(end, (int)fSizeIntro); i++) { vr[0].p = v1a[i]; vr[1].p = v1b[i]; vr[2].p = v1a[i+1]; vr[3].p = v1b[i+1]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } else { for(int i = 0; i < std::min(end, (int)fSizeIntro); i++) { vr[0].p = va[i]; vr[1].p = vb[i]; vr[2].p = va[i+1]; vr[3].p = vb[i+1]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } //------------------------------------------------------------------------- // rendu de la bordure mat.setBlendType(RenderMaterial::Additive); vr[0].color = vr[1].color = Color::black.toRGB(); vr[2].color = vr[3].color = m_colorBorder.toRGB(); for(int i = 0; i < std::min(end, (int)fSizeIntro); i++) { vt[2] = va[i] - (va[i] - m_eSrc) * 0.2f; vt[3] = va[i + 1] - (va[i + 1] - m_eSrc) * 0.2f; vr[0].p = vt[3]; vr[1].p = vt[2]; vr[2].p = va[i+1]; vr[3].p = va[i]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); vt[2] = vb[i] - (vb[i] - m_eSrc) * 0.2f; vt[3] = vb[i + 1] - (vb[i + 1] - m_eSrc) * 0.2f; vr[3].p = vb[i]; vr[2].p = vb[i+1]; vr[1].p = vt[2]; vr[0].p = vt[3]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } //------------------------------------------------------------------------- // rendu des faisceaux // blend additif ou mul // smooth sur les cotés ou pas .. // texture sympa avec glow au milieu ou uv wrap mat.setWrapMode(TextureStage::WrapMirror); mat.setTexture(tex_light); target.x = m_eSrc.x ; target.y = m_eSrc.y + 1.5f * sizeF; target.z = m_eSrc.z ; vr[0].color = vr[1].color = m_colorRays1.toRGB(); vr[2].color = vr[3].color = m_colorRays2.toRGB(); vr[0].uv = Vec2f(0, 1); vr[1].uv = Vec2f(1, 1); vr[2].uv = Vec2f(0, 0); vr[3].uv = Vec2f(1, 0); for(int i = 0; i < end - 1; i++) { float t = Random::getf(); if(t <= 0.15f) { if(tfRaysa[i] < 1.0f) tfRaysa[i] += 0.02f; if(tfRaysa[i+1] < 1.0f) tfRaysa[i+1] += 0.01f; if(tfRaysa[i] > 1.0f) tfRaysa[i] = 1.0f; if(tfRaysa[i+1] > 1.0f) tfRaysa[i+1] = 1.0f; } if(t >= 0.9f) { if(tfRaysa[i] > 0.0f) tfRaysa[i] -= 0.02f; if(tfRaysa[i+1] > 0.0f) tfRaysa[i+1] -= 0.01f; if(tfRaysa[i] < 0.0f) tfRaysa[i] = 0.0f; if(tfRaysa[i+1] < 0.0f) tfRaysa[i+1] = 0.0f; } float t2 = Random::getf(); if(t2 <= 0.15f) { if(tfRaysb[i] < 1.0f) tfRaysb[i] += 0.02f; if(tfRaysb[i+1] < 1.0f) tfRaysb[i+1] += 0.01f; if(tfRaysb[i] > 1.0f) tfRaysb[i] = 1.0f; if(tfRaysb[i+1] > 1.0f) tfRaysb[i+1] = 1.0f; } if(t2 >= 0.9f) { if(tfRaysb[i] > 0.0f) tfRaysb[i] -= 0.02f; if(tfRaysb[i+1] > 0.0f) tfRaysb[i+1] -= 0.01f; if(tfRaysb[i] < 0.0f) tfRaysb[i] = 0.0f; if(tfRaysb[i+1] < 0.0f) tfRaysb[i+1] = 0.0f; } if(i < fSizeIntro) { vt[0] = va[i]; vt[1] = va[i + 1]; vt[2].x = va[i].x ; vt[2].y = va[i].y + (va[i].y - target.y) * 2; vt[2].z = va[i].z ; vt[3].x = va[i+1].x ; vt[3].y = va[i+1].y + (va[i+1].y - target.y) * 2; vt[3].z = va[i+1].z ; vr[0].color = (m_colorRays1 * tfRaysa[i]).toRGB(); vr[1].color = (m_colorRays1* tfRaysa[i + 1]).toRGB(); vr[2].color = (m_colorRays2 * tfRaysa[i]).toRGB(); vr[3].color = (m_colorRays2 * tfRaysa[i + 1]).toRGB(); vr[0].p = vt[0]; vr[1].p = vt[1]; vr[2].p = vt[2]; vr[3].p = vt[3]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } if(i < fSizeIntro) { vt[0] = vb[i + 1]; vt[1] = vb[i]; vt[2].x = vb[i+1].x ; vt[2].y = vb[i+1].y + (vb[i+1].y - target.y) * 2; vt[2].z = vb[i+1].z ; vt[3].x = vb[i].x ; vt[3].y = vb[i].y + (vb[i].y - target.y) * 2; vt[3].z = vb[i].z ; vr[0].color = (m_colorRays1 * tfRaysb[i]).toRGB(); vr[1].color = (m_colorRays1 * tfRaysb[i + 1]).toRGB(); vr[2].color = (m_colorRays2 * tfRaysb[i]).toRGB(); vr[3].color = (m_colorRays2 * tfRaysb[i + 1]).toRGB(); vr[0].p = vt[0]; vr[1].p = vt[1]; vr[2].p = vt[2]; vr[3].p = vt[3]; drawTriangle(mat, &vr[0]); drawTriangle(mat, &vr[1]); } } }
void CMagicMissile::Render() { Vec3f lastpos, newpos; Vec3f v; if(ulCurrentTime >= ulDuration) return; RenderMaterial mat; mat.setCulling(CullNone); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); if(tex_mm) mat.setTexture(tex_mm); if(bMove) { float fOneOnDuration = 1.f / (float)(ulDuration); fTrail = (ulCurrentTime * fOneOnDuration) * (iBezierPrecision + 2) * 5; } newpos = lastpos = pathways[0]; for(int i = 0; i < 5; i++) { int kp = i; int kpprec = (i > 0) ? kp - 1 : kp ; int kpsuiv = kp + 1 ; int kpsuivsuiv = (i < (5 - 2)) ? kpsuiv + 1 : kpsuiv; for(int toto = 1; toto < iBezierPrecision; toto++) { if(fTrail < i * iBezierPrecision + toto) break; float t = toto * fOneOnBezierPrecision; float t1 = t; float t2 = t1 * t1 ; float t3 = t2 * t1 ; float f0 = 2.f * t3 - 3.f * t2 + 1.f ; float f1 = -2.f * t3 + 3.f * t2 ; float f2 = t3 - 2.f * t2 + t1 ; float f3 = t3 - t2 ; float val = pathways[kpsuiv].x; float p0 = 0.5f * (val - pathways[kpprec].x) ; float p1 = 0.5f * (pathways[kpsuivsuiv].x - pathways[kp].x) ; v.x = f0 * pathways[kp].x + f1 * val + f2 * p0 + f3 * p1 ; val = pathways[kpsuiv].y ; p0 = 0.5f * (val - pathways[kpprec].y) ; p1 = 0.5f * (pathways[kpsuivsuiv].y - pathways[kp].y) ; v.y = f0 * pathways[kp].y + f1 * val + f2 * p0 + f3 * p1 ; val = pathways[kpsuiv].z ; p0 = 0.5f * (val - pathways[kpprec].z) ; p1 = 0.5f * (pathways[kpsuivsuiv].z - pathways[kp].z) ; v.z = f0 * pathways[kp].z + f1 * val + f2 * p0 + f3 * p1 ; newpos = v; if(!((fTrail - (i * iBezierPrecision + toto)) > iLength)) { float c; if(fTrail < iLength) { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / fTrail); } else { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / (float)iLength); } float fsize = c; float alpha = c - 0.2f; if(alpha < 0.2f) alpha = 0.2f; c += Random::getf(-0.1f, 0.1f); c = glm::clamp(c, 0.f, 1.f); Color color = (m_trailColor * (c * alpha)).to<u8>(); if(fsize < 0.5f) fsize = fsize * 2 * 3; else fsize = (1.0f - fsize + 0.5f) * 2 * (3 * 0.5f); float fs = fsize * 6 + Random::getf(0.f, 0.3f); float fe = fsize * 6 + Random::getf(0.f, 0.3f); Draw3DLineTexNew(mat, lastpos, newpos, color, color, fs, fe); } Vec3f temp_vector = lastpos; lastpos = newpos; newpos = temp_vector; } } Vec3f av = newpos - lastpos; float bubu = getAngle(av.x, av.z, 0, 0); float bubu1 = getAngle(av.x, av.y, 0, 0); eCurPos = lastpos; Anglef stiteangle; stiteangle.setPitch(-glm::degrees(bubu)); stiteangle.setYaw(0); stiteangle.setRoll(-(glm::degrees(bubu1))); if(av.x < 0) stiteangle.setRoll(stiteangle.getRoll() - 90); if(av.x > 0) stiteangle.setRoll(stiteangle.getRoll() + 90); if(stiteangle.getRoll() < 0) stiteangle.setRoll(stiteangle.getRoll() + 360.0f); Draw3DObject(smissile, stiteangle, eCurPos, Vec3f_ONE, m_projectileColor, mat); }
void BlessSpell::Update(float timeDelta) { fRot += timeDelta * 0.25f; if(ValidIONum(m_target)) { m_pos = entities[m_target]->pos; if(m_target == PlayerEntityHandle) m_yaw = player.angle.getPitch(); else m_yaw = entities[m_target]->angle.getPitch(); } m_scale = (m_level + 10) * 6.f; Vec3f pos = m_pos + Vec3f(0, -5, 0); RenderMaterial mat; mat.setCulling(Renderer::CullNone); mat.setBlendType(RenderMaterial::Additive); mat.setDepthTest(true); mat.setLayer(RenderMaterial::Decal); mat.setTexture(tex_sol); float fBetaRadCos = glm::cos(glm::radians(MAKEANGLE(m_yaw))) * m_scale; float fBetaRadSin = glm::sin(glm::radians(MAKEANGLE(m_yaw))) * m_scale; ColorRGBA color = Color::white.toRGB(); { TexturedQuad q; q.v[0].color = color; q.v[1].color = color; q.v[2].color = color; q.v[3].color = color; q.v[0].uv = Vec2f_ZERO; q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f_Y_AXIS; q.v[0].p.x = pos.x + fBetaRadCos - fBetaRadSin; q.v[0].p.y = pos.y; q.v[0].p.z = pos.z + fBetaRadSin + fBetaRadCos; q.v[1].p.x = pos.x - fBetaRadCos - fBetaRadSin; q.v[1].p.y = pos.y; q.v[1].p.z = pos.z - fBetaRadSin + fBetaRadCos; q.v[2].p.x = pos.x - fBetaRadCos + fBetaRadSin; q.v[2].p.y = pos.y; q.v[2].p.z = pos.z - fBetaRadSin - fBetaRadCos; q.v[3].p.x = pos.x + fBetaRadCos + fBetaRadSin; q.v[3].p.y = pos.y; q.v[3].p.z = pos.z + fBetaRadSin - fBetaRadCos; drawQuadRTP(mat, q); } for(int i = 0; i < 12; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = m_pos - Vec3f(0.f, 20.f, 0.f); pd->move = Vec3f(3.f * frand2(), rnd() * 0.5f, 3.f * frand2()); pd->siz = 0.005f; pd->tolive = Random::get(1000, 2000); pd->tc = tex_p1; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.6f, 0.2f); } }
void ARX_MAGICAL_FLARES_Update() { if(!g_magicFlaresCount) return; shinum++; if(shinum >= 10) { shinum = 1; } PlatformDuration diff = g_platformTime.lastFrameDuration(); bool key = !GInput->actionPressed(CONTROLS_CUST_MAGICMODE); RenderMaterial mat; mat.setBlendType(RenderMaterial::Additive); EERIE_LIGHT * light = lightHandleGet(torchLightHandle); for(long j = 1; j < 5; j++) { TextureContainer * surf; switch(j) { case 2: surf = g_magicFlareTextures.lumignon; break; case 3: surf = g_magicFlareTextures.lumignon2; break; case 4: surf = g_magicFlareTextures.plasm; break; default: surf = g_magicFlareTextures.shine[shinum]; break; } mat.setTexture(surf); for(size_t i = 0; i < g_magicFlaresMax; i++) { MagicFlare & flare = g_magicFlares[i]; if(!flare.exist || flare.type != j) { continue; } flare.tolive -= diff * 2; if(flare.flags & 1) { flare.tolive -= diff * 4; } else if(key) { flare.tolive -= diff * 6; } float z = flare.tolive / PlatformDurationMs(4000); float size; if(flare.type == 1) { size = flare.size * 2 * z; } else if(flare.type == 4) { size = flare.size * 2.f * z * (4.0f / 3.0f); } else { size = flare.size; } if(flare.tolive <= 0 || flare.pos.y < -64.f || size < 3.f) { removeFlare(flare); continue; } if(flare.type == 1 && z < 0.6f) { z = 0.6f; } Color3f color = flare.rgb * z; light->rgb = componentwise_max(light->rgb, color); EERIE_LIGHT * el = lightHandleGet(flare.dynlight); if(el) { el->pos = flare.p; el->rgb = color; } mat.setDepthTest(flare.io != NULL); if(flare.bDrawBitmap) { Vec3f pos = Vec3f(flare.p.x - size / 2.0f, flare.p.y - size / 2.0f, flare.p.z); EERIEAddBitmap(mat, pos, size, size, surf, Color(color)); } else { EERIEAddSprite(mat, flare.p, size * 0.025f + 1.f, Color(color), 2.f); } } } light->rgb = componentwise_min(light->rgb, Color3f::white); }
void CBless::Render() { int i = 0; float x = eSrc.x; float y = eSrc.y - 5; float z = eSrc.z; if(ulCurrentTime >= ulDuration) return; RenderMaterial mat; mat.setCulling(Renderer::CullNone); mat.setBlendType(RenderMaterial::Additive); mat.setDepthTest(true); mat.setLayer(RenderMaterial::Decal); mat.setTexture(tex_sol); float fBetaRadCos = glm::cos(glm::radians(MAKEANGLE(m_yaw))) * m_scale; float fBetaRadSin = glm::sin(glm::radians(MAKEANGLE(m_yaw))) * m_scale; ColorRGBA color = Color::white.toRGB(); { TexturedQuad q; q.v[0].color = color; q.v[1].color = color; q.v[2].color = color; q.v[3].color = color; q.v[0].uv = Vec2f_ZERO; q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f_Y_AXIS; q.v[0].p.x = x + fBetaRadCos - fBetaRadSin; q.v[0].p.y = y; q.v[0].p.z = z + fBetaRadSin + fBetaRadCos; q.v[1].p.x = x - fBetaRadCos - fBetaRadSin; q.v[1].p.y = y; q.v[1].p.z = z - fBetaRadSin + fBetaRadCos; q.v[2].p.x = x - fBetaRadCos + fBetaRadSin; q.v[2].p.y = y; q.v[2].p.z = z - fBetaRadSin - fBetaRadCos; q.v[3].p.x = x + fBetaRadCos + fBetaRadSin; q.v[3].p.y = y; q.v[3].p.z = z + fBetaRadSin - fBetaRadCos; drawQuadRTP(mat, q); } for(i = 0; i < 12; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = eSrc - Vec3f(0.f, 20.f, 0.f); pd->move = Vec3f(3.f * frand2(), rnd() * 0.5f, 3.f * frand2()); pd->siz = 0.005f; pd->tolive = Random::get(1000, 2000); pd->tc = tex_p1; pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING; pd->fparam = 0.0000001f; pd->rgb = Color3f(0.7f, 0.6f, 0.2f); } }
void CLevitate::Render() { if(this->key > 1) return; //calcul du cone TexturedVertex *d3dv; Vec3f * vertex; int nb, nbc, col; float ddu = this->ang; float u = ddu, du = .99999999f / (float)this->def; switch(this->key) { case 0: nbc = 2; while(nbc--) { vertex = this->cone[nbc].conevertex; d3dv = this->cone[nbc].coned3d; nb = (this->cone[nbc].conenbvertex) >> 1; while(nb) { Vec3f d3dvs; d3dvs.x = m_pos.x + (vertex + 1)->x + ((vertex->x - (vertex + 1)->x) * m_coneScale); d3dvs.y = m_pos.y + (vertex + 1)->y + ((vertex->y - (vertex + 1)->y) * m_coneScale); d3dvs.z = m_pos.z + (vertex + 1)->z + ((vertex->z - (vertex + 1)->z) * m_coneScale); d3dv->p = EE_RT(d3dvs); col = Random::get(0, 80); if(!arxtime.is_paused()) d3dv->color = Color::grayb(col).toRGB(col); d3dv->uv.x = u; d3dv->uv.y = 0.f; vertex++; d3dv++; d3dvs.x = m_pos.x + vertex->x; d3dvs.y = m_pos.y; d3dvs.z = m_pos.z + vertex->z; d3dv->p = EE_RT(d3dvs); col = Random::get(0, 80); if(!arxtime.is_paused()) d3dv->color = Color::black.toRGB(col); d3dv->uv.x = u; d3dv->uv.y = 1.f; vertex++; d3dv++; u += du; nb--; } u = ddu; du = -du; } break; case 1: nbc = 2; while(nbc--) { vertex = this->cone[nbc].conevertex; d3dv = this->cone[nbc].coned3d; nb = (this->cone[nbc].conenbvertex) >> 1; while(nb) { Vec3f d3dvs = m_pos + *vertex; d3dv->p = EE_RT(d3dvs); col = Random::get(0, 80); if(!arxtime.is_paused()) d3dv->color = Color::grayb(col).toRGB(col); d3dv->uv.x = u; d3dv->uv.y = 0.f; vertex++; d3dv++; d3dvs.x = m_pos.x + vertex->x; d3dvs.y = m_pos.y; d3dvs.z = m_pos.z + vertex->z; d3dv->p = EE_RT(d3dvs); col = Random::get(0, 80); if(!arxtime.is_paused()) d3dv->color = Color::black.toRGB(col); d3dv->uv.x = u; d3dv->uv.y = 1.f; vertex++; d3dv++; u += du; nb--; } u = ddu; du = -du; } break; } //tracé du cone back RenderMaterial mat; mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); mat.setWrapMode(TextureStage::WrapMirror); mat.setTexture(tsouffle); mat.setCulling(Renderer::CullCW); int i = cone[1].conenbfaces - 2; int j = 0; while(i--) { drawTriangle(mat, &cone[1].coned3d[j]); j++; } i = cone[0].conenbfaces - 2; j = 0; while(i--) { drawTriangle(mat, &cone[0].coned3d[j]); j++; } //tracé du cone front mat.setCulling(Renderer::CullCCW); i = cone[1].conenbfaces - 2; j = 0; while(i--) { drawTriangle(mat, &cone[1].coned3d[j]); j++; } i = cone[0].conenbfaces - 2; j = 0; while(i--) { drawTriangle(mat, &cone[0].coned3d[j]); j++; } this->DrawStone(); }
void CCreateField::Render() { if(!VisibleSphere(Sphere(eSrc - Vec3f(0.f, 120.f, 0.f), 400.f))) return; //------------------------------------------------------------------------- // rendu if(youp) { fglow += 0.5f; if(fglow >= 50) { youp = false; } } else { fglow -= 0.5f; if(fglow <= 0) { youp = true; } } float ysize = std::min(1.0f, m_elapsed / GameDurationMs(1000)); if(ysize >= 1.0f) { size = std::min(1.0f, (m_elapsed - GameDurationMs(1000)) / GameDurationMs(1000)); size = std::max(size, 0.1f); } // ondulation ft += 0.01f; if(ft > 360.0f) { ft = 0.0f; } falpha = glm::sin(glm::radians(fglow)) + Random::getf(0.f, 0.2f); falpha = glm::clamp(falpha, 0.f, 1.f); float smul = 100 * size; // bottom points Vec3f b[4] = { eSrc + Vec3f(-smul, 0.f, -smul), eSrc + Vec3f(smul, 0.f, -smul), eSrc + Vec3f(smul, 0.f, smul), eSrc + Vec3f(-smul, 0.f, smul) }; // top points Vec3f t[4] = { b[0] + Vec3f(0.f, -250 * ysize, 0.f), b[1] + Vec3f(0.f, -250 * ysize, 0.f), b[2] + Vec3f(0.f, -250 * ysize, 0.f), b[3] + Vec3f(0.f, -250 * ysize, 0.f) }; fwrap -= 5.0f; // TODO ignores the frame delay while(fwrap < 0) { fwrap += 360; } RenderMaterial mat; mat.setTexture(tex_jelly); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); RenderSubDivFace(b, b, 0, 1, 2, 3, mat); RenderSubDivFace(t, t, 0, 3, 2, 1, mat); RenderSubDivFace(b, t, 1, 0, 0, 1, mat); RenderSubDivFace(b, t, 3, 2, 2, 3, mat); RenderSubDivFace(b, t, 0, 3, 3, 0, mat); RenderSubDivFace(b, t, 2, 1, 1, 2, mat); EERIE_LIGHT * light = lightHandleGet(lLightId); if(light) { light->intensity = 0.7f + 2.3f * falpha; light->fallend = 500.f; light->fallstart = 400.f; light->rgb = Color3f(0.8f, 0.0f, 1.0f); light->pos = eSrc + Vec3f(0.f, -150.f, 0.f); light->duration = GameDurationMs(800); } }
void CCreateField::Render() { if(!VisibleSphere(eSrc - Vec3f(0.f, 120.f, 0.f), 400.f)) return; if(ulCurrentTime >= ulDuration) return; float fOneOnDuration = 1.f / (float)(ulDuration); falpha = 1.f - (((float)(ulCurrentTime)) * fOneOnDuration); if (falpha > 1.f) falpha = 1.f; //------------------------------------------------------------------------- // rendu if(youp) { fglow += 0.5f; if(fglow >= 50) { youp = false; } } else { fglow -= 0.5f; if(fglow <= 0) { youp = true; } } ysize = std::min(1.0f, ulCurrentTime * 0.001f); if(ysize >= 1.0f) { size = std::min(1.0f, (ulCurrentTime - 1000) * 0.001f); size = std::max(size, 0.1f); } // ondulation ft += 0.01f; if(ft > 360.0f) { ft = 0.0f; } falpha = glm::sin(glm::radians(fglow)) + rnd() * 0.2f; falpha = glm::clamp(falpha, 0.f, 1.f); float x = eSrc.x; float y = eSrc.y; float z = eSrc.z; float smul = 100 * size; // bottom points b[0].x = x - smul; b[0].y = y; b[0].z = z - smul; b[1].x = x + smul; b[1].y = y; b[1].z = z - smul; b[2].x = x + smul; b[2].y = y; b[2].z = z + smul; b[3].x = x - smul; b[3].y = y; b[3].z = z + smul; // top points t[0].x = x - smul; t[0].y = y - 250 * ysize; t[0].z = z - smul; t[1].x = x + smul; t[1].y = y - 250 * ysize; t[1].z = z - smul; t[2].x = x + smul; t[2].y = y - 250 * ysize; t[2].z = z + smul; t[3].x = x - smul; t[3].y = y - 250 * ysize; t[3].z = z + smul; fwrap -= 5.0f; // TODO ignores the frame delay while(fwrap < 0) { fwrap += 360; } RenderMaterial mat = RenderMaterial::getCurrent(); mat.setTexture(tex_jelly); mat.setWrapMode(TextureStage::WrapRepeat); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); RenderSubDivFace(b, b, 0, 1, 2, 3, mat); RenderSubDivFace(t, t, 0, 3, 2, 1, mat); RenderSubDivFace(b, t, 1, 0, 0, 1, mat); RenderSubDivFace(b, t, 3, 2, 2, 3, mat); RenderSubDivFace(b, t, 0, 3, 3, 0, mat); RenderSubDivFace(b, t, 2, 1, 1, 2, mat); if(lightHandleIsValid(lLightId)) { EERIE_LIGHT * light = lightHandleGet(lLightId); light->intensity = 0.7f + 2.3f * falpha; light->fallend = 500.f; light->fallstart = 400.f; light->rgb.r = 0.8f; light->rgb.g = 0.0f; light->rgb.b = 1.0f; light->pos.x = eSrc.x; light->pos.y = eSrc.y - 150; light->pos.z = eSrc.z; light->duration = 800; } //return falpha; }
void ARX_MAGICAL_FLARES_Update() { if(!flarenum) return; shinum++; if(shinum >= 10) { shinum = 1; } long TICKS = long(arxtime) - FRAMETICKS; FRAMETICKS = (unsigned long)(arxtime); if(TICKS < 0) { return; } bool key = !GInput->actionPressed(CONTROLS_CUST_MAGICMODE); RenderMaterial mat; mat.setBlendType(RenderMaterial::Additive); EERIE_LIGHT * light = lightHandleGet(torchLightHandle); for(long j = 1; j < 5; j++) { TextureContainer * surf; switch(j) { case 2: surf = flaretc.lumignon; break; case 3: surf = flaretc.lumignon2; break; case 4: surf = flaretc.plasm; break; default: surf = flaretc.shine[shinum]; break; } mat.setTexture(surf); for(size_t i = 0; i < MAX_FLARES; i++) { FLARES & flare = magicFlares[i]; if(!flare.exist || flare.type != j) { continue; } flare.tolive -= float(TICKS * 2); if(flare.flags & 1) { flare.tolive -= float(TICKS * 4); } else if (key) { flare.tolive -= float(TICKS * 6); } float z = (flare.tolive * 0.00025f); float s; if(flare.type == 1) { s = flare.size * 2 * z; } else if(flare.type == 4) { s = flare.size * 2.f * z + 10.f; } else { s = flare.size; } if(flare.tolive <= 0.f || flare.pos.y < -64.f || s < 3.f) { if(flare.io && ValidIOAddress(flare.io)) { flare.io->flarecount--; } lightHandleDestroy(flare.dynlight); flare.exist = 0; flarenum--; continue; } if(flare.type == 1 && z < 0.6f) { z = 0.6f; } Color3f c = flare.rgb * z; flare.tv.color = c.toRGB(); flare.v.p = flare.tv.p; light->rgb = componentwise_max(light->rgb, c); if(lightHandleIsValid(flare.dynlight)) { EERIE_LIGHT * el = lightHandleGet(flare.dynlight); el->pos = flare.v.p; el->rgb = c; } mat.setDepthTest(flare.io != NULL); if(flare.bDrawBitmap) { s *= 2.f; EERIEAddBitmap(mat, flare.v.p, s, s, surf, Color::fromRGBA(flare.tv.color)); } else { EERIEAddSprite(mat, flare.v.p, s * 0.025f + 1.f, Color::fromRGBA(flare.tv.color), 2.f); } } } light->rgb = componentwise_min(light->rgb, Color3f::white); }
void CMagicMissile::Render() { Vec3f lastpos, newpos; Vec3f v; if(ulCurrentTime >= ulDuration) return; RenderMaterial mat; mat.setCulling(CullNone); mat.setDepthTest(true); mat.setBlendType(RenderMaterial::Additive); if(tex_mm) mat.setTexture(tex_mm); if(bMove) { float fOneOnDuration = 1.f / (float)(ulDuration); fTrail = (ulCurrentTime * fOneOnDuration) * (iBezierPrecision + 2) * 5; } newpos = lastpos = pathways[0]; for(int i = 0; i < 5; i++) { const Vec3f v1 = pathways[std::max(0, i - 1)]; const Vec3f v2 = pathways[i]; const Vec3f v3 = pathways[i + 1]; const Vec3f v4 = pathways[std::min(5, i + 2)]; for(int toto = 1; toto < iBezierPrecision; toto++) { if(fTrail < i * iBezierPrecision + toto) break; float t = toto * (1.0f / iBezierPrecision); v = glm::catmullRom(v1, v2, v3, v4, t); newpos = v; if(!((fTrail - (i * iBezierPrecision + toto)) > iLength)) { float c; if(fTrail < iLength) { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / fTrail); } else { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / (float)iLength); } float fsize = c; float alpha = c - 0.2f; if(alpha < 0.2f) alpha = 0.2f; c += Random::getf(-0.1f, 0.1f); c = glm::clamp(c, 0.f, 1.f); Color color = (m_trailColor * (c * alpha)).to<u8>(); if(fsize < 0.5f) fsize = fsize * 2 * 3; else fsize = (1.0f - fsize + 0.5f) * 2 * (3 * 0.5f); float fs = fsize * 6 + Random::getf(0.f, 0.3f); float fe = fsize * 6 + Random::getf(0.f, 0.3f); Draw3DLineTexNew(mat, lastpos, newpos, color, color, fs, fe); } Vec3f temp_vector = lastpos; lastpos = newpos; newpos = temp_vector; } } Vec3f av = newpos - lastpos; float bubu = getAngle(av.x, av.z, 0, 0); float bubu1 = getAngle(av.x, av.y, 0, 0); eCurPos = lastpos; Anglef stiteangle; stiteangle.setPitch(-glm::degrees(bubu)); stiteangle.setYaw(0); stiteangle.setRoll(-(glm::degrees(bubu1))); if(av.x < 0) stiteangle.setRoll(stiteangle.getRoll() - 90); if(av.x > 0) stiteangle.setRoll(stiteangle.getRoll() + 90); if(stiteangle.getRoll() < 0) stiteangle.setRoll(stiteangle.getRoll() + 360.0f); Draw3DObject(smissile, stiteangle, eCurPos, Vec3f_ONE, m_projectileColor, mat); }
void BlessSpell::Update() { fRot += g_gameTime.lastFrameDuration() / GameDurationMs(4); Entity * target = entities.get(m_target); if(target) { m_pos = target->pos; if(m_target == EntityHandle_Player) m_yaw = player.angle.getYaw(); else m_yaw = target->angle.getYaw(); } m_scale = (m_level + 10) * 6.f; Vec3f pos = m_pos + Vec3f(0, -5, 0); RenderMaterial mat; mat.setCulling(CullNone); mat.setBlendType(RenderMaterial::Additive); mat.setDepthTest(true); mat.setLayer(RenderMaterial::Decal); mat.setTexture(tex_sol); float fBetaRadCos = glm::cos(glm::radians(MAKEANGLE(m_yaw))) * m_scale; float fBetaRadSin = glm::sin(glm::radians(MAKEANGLE(m_yaw))) * m_scale; ColorRGBA color = Color::white.toRGB(); { TexturedQuad q; q.v[0].color = color; q.v[1].color = color; q.v[2].color = color; q.v[3].color = color; q.v[0].uv = Vec2f_ZERO; q.v[1].uv = Vec2f_X_AXIS; q.v[2].uv = Vec2f_ONE; q.v[3].uv = Vec2f_Y_AXIS; q.v[0].p.x = pos.x + fBetaRadCos - fBetaRadSin; q.v[0].p.y = pos.y; q.v[0].p.z = pos.z + fBetaRadSin + fBetaRadCos; q.v[1].p.x = pos.x - fBetaRadCos - fBetaRadSin; q.v[1].p.y = pos.y; q.v[1].p.z = pos.z - fBetaRadSin + fBetaRadCos; q.v[2].p.x = pos.x - fBetaRadCos + fBetaRadSin; q.v[2].p.y = pos.y; q.v[2].p.z = pos.z - fBetaRadSin - fBetaRadCos; q.v[3].p.x = pos.x + fBetaRadCos + fBetaRadSin; q.v[3].p.y = pos.y; q.v[3].p.z = pos.z + fBetaRadSin - fBetaRadCos; drawQuadRTP(mat, q); } for(int i = 0; i < 12; i++) { PARTICLE_DEF * pd = createParticle(); if(!pd) { break; } pd->ov = m_pos - Vec3f(0.f, 20.f, 0.f); pd->move = arx::linearRand(Vec3f(-3.f, 0.f, -3.f), Vec3f(3.f, 0.5f, 3.f)); pd->siz = 0.005f; pd->tolive = Random::getu(1000, 2000); pd->tc = tex_p1; pd->m_flags = FADE_IN_AND_OUT | ROTATING | DISSIPATING; pd->m_rotation = 0.0000001f; pd->rgb = Color3f(0.7f, 0.6f, 0.2f); } }