static Vec3f GetChestPos(EntityHandle num) { if(num == 0) { return player.pos + Vec3f(0.f, 70.f, 0.f); } if(ValidIONum(num)) { long idx = GetGroupOriginByName(entities[num]->obj, "chest"); if(idx >= 0) { return entities[num]->obj->vertexlist3[idx].v; } else { return entities[num]->pos + Vec3f(0.f, -120.f, 0.f); } } else { // should not happen return Vec3f_ZERO; } }
static Vec3f GetChestPos(EntityHandle num) { if(num == EntityHandle_Player) { return player.pos + Vec3f(0.f, 70.f, 0.f); } Entity * io = entities.get(num); if(!io) { // should not happen return Vec3f(0.f); } ObjVertHandle idx = GetGroupOriginByName(io->obj, "chest"); if(idx != ObjVertHandle()) { return io->obj->vertexWorldPositions[idx.handleData()].v; } return io->pos + Vec3f(0.f, -120.f, 0.f); }
void LightningStrikeSpell::Update(float timeDelta) { float fBeta = 0.f; float falpha = 0.f; Entity * caster = entities[m_caster]; long idx = GetGroupOriginByName(caster->obj, "chest"); if(idx >= 0) { m_caster_pos = caster->obj->vertexlist3[idx].v; } else { m_caster_pos = caster->pos; } if(m_caster == PlayerEntityHandle) { falpha = -player.angle.getYaw(); fBeta = player.angle.getPitch(); } else { fBeta = caster->angle.getPitch(); if(ValidIONum(caster->targetinfo) && caster->targetinfo != m_caster) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(caster->targetinfo); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } else if(ValidIONum(m_target)) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(m_target); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); //alpha entre orgn et dest; } } m_lightning.m_pos = m_caster_pos; m_lightning.m_beta = fBeta; m_lightning.m_alpha = falpha; m_lightning.m_caster = m_caster; m_lightning.m_level = m_level; m_lightning.Update(timeDelta); m_lightning.Render(); ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos); }
void LightningStrikeSpell::Update() { float fBeta = 0.f; float falpha = 0.f; Entity * caster = entities[m_caster]; ObjVertHandle idx = GetGroupOriginByName(caster->obj, "chest"); if(idx != ObjVertHandle()) { m_caster_pos = caster->obj->vertexWorldPositions[idx.handleData()].v; } else { m_caster_pos = caster->pos; } if(m_caster == EntityHandle_Player) { falpha = -player.angle.getPitch(); fBeta = player.angle.getYaw(); } else { fBeta = caster->angle.getYaw(); if(ValidIONum(caster->targetinfo) && caster->targetinfo != m_caster) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(caster->targetinfo); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); } else if(ValidIONum(m_target)) { const Vec3f & p1 = m_caster_pos; Vec3f p2 = GetChestPos(m_target); falpha = MAKEANGLE(glm::degrees(getAngle(p1.y, p1.z, p2.y, p2.z + glm::distance(Vec2f(p2.x, p2.z), Vec2f(p1.x, p1.z))))); } } m_lightning.m_pos = m_caster_pos; m_lightning.m_beta = fBeta; m_lightning.m_alpha = falpha; m_lightning.m_caster = m_caster; m_lightning.m_level = m_level; m_lightning.Update(g_gameTime.lastFrameDuration()); m_lightning.Render(); ARX_SOUND_RefreshPosition(m_snd_loop, entities[m_caster]->pos); }
// Converts a Theo Object to an EERIE object static EERIE_3DOBJ * TheoToEerie(const char * adr, long size, const res::path & texpath, const res::path & fic) { LogWarning << "TheoToEerie " << fic; if(!adr) return NULL; res::path txpath = texpath.empty() ? "graph/obj3d/textures" : texpath; if(size < 10) { return NULL; } size_t pos = 0; const THEO_HEADER * pth = reinterpret_cast<const THEO_HEADER *>(adr + pos); pos += sizeof(THEO_HEADER); if(pth->version < 3003 || pth->version > 3011) { LogError << "TheoToEerie: invalid version in " << fic << ": found " << pth->version << " expected 3004 to 3011"; return NULL; } EERIE_3DOBJ * eerie = new EERIE_3DOBJ; eerie->clear(); eerie->file = fic; if(pth->type_write == 0) { // read the texture LogError << "WARNING object " << fic << " SAVE MAP IN OBJECT = INVALID... Using Dummy Textures..."; eerie->texturecontainer.resize(pth->nb_maps); for(long i = 0; i < pth->nb_maps; i++) { pos += sizeof(THEO_TEXTURE); eerie->texturecontainer[i] = GetAnyTexture(); } } else { if((pth->type_write & SAVE_MAP_BMP) || (pth->type_write & SAVE_MAP_TGA)) { eerie->texturecontainer.resize(pth->nb_maps); for(long i = 0; i < pth->nb_maps; i++) { res::path name; if(pth->version >= 3008) { const THEO_SAVE_MAPS_IN_3019 * tsmi3019 = reinterpret_cast<const THEO_SAVE_MAPS_IN_3019 *>(adr + pos); pos += sizeof(THEO_SAVE_MAPS_IN_3019); name = res::path::load(util::loadString(tsmi3019->texture_name)).remove_ext(); } else { const THEO_SAVE_MAPS_IN * tsmi = reinterpret_cast<const THEO_SAVE_MAPS_IN *>(adr + pos); pos += sizeof(THEO_SAVE_MAPS_IN); name = res::path::load(util::loadString(tsmi->texture_name)).remove_ext(); } if(!name.empty()) { eerie->texturecontainer[i] = TextureContainer::Load(txpath / name, TextureContainer::Level); } } } } pos = pth->object_seek; loadObjectData(eerie, adr, &pos, pth->version); eerie->angle = Anglef::ZERO; eerie->pos = Vec3f_ZERO; // NORMALS CALCULATIONS //Compute Faces Areas for(size_t i = 0; i < eerie->facelist.size(); i++) { const Vec3f & p0 = eerie->vertexlist[eerie->facelist[i].vid[0]].v; const Vec3f & p1 = eerie->vertexlist[eerie->facelist[i].vid[1]].v; const Vec3f & p2 = eerie->vertexlist[eerie->facelist[i].vid[2]].v; eerie->facelist[i].temp = glm::distance((p0 + p1) * .5f, p2) * glm::distance(p0, p1) * .5f; } for(size_t i = 0; i < eerie->facelist.size(); i++) { CalcObjFaceNormal( &eerie->vertexlist[eerie->facelist[i].vid[0]].v, &eerie->vertexlist[eerie->facelist[i].vid[1]].v, &eerie->vertexlist[eerie->facelist[i].vid[2]].v, &eerie->facelist[i] ); float area = eerie->facelist[i].temp; for(long j = 0; j < 3; j++) { float mod = area * area; Vec3f nrml = eerie->facelist[i].norm * mod; float count = mod; for(size_t i2 = 0; i2 < eerie->facelist.size(); i2++) { if(i != i2) { float area2 = eerie->facelist[i].temp; for(long j2 = 0; j2 < 3; j2++) { if(closerThan(eerie->vertexlist[eerie->facelist[i2].vid[j2]].v, eerie->vertexlist[eerie->facelist[i].vid[j]].v, .1f)) { mod = (area2 * area2); nrml += eerie->facelist[i2].norm * mod; count += mod; } } } } count = 1.f / count; eerie->vertexlist[eerie->facelist[i].vid[j]].vert.p = nrml * count; } } for(size_t i = 0; i < eerie->facelist.size(); i++) { for(long j = 0; j < 3; j++) { eerie->vertexlist[eerie->facelist[i].vid[j]].norm = eerie->vertexlist[eerie->facelist[i].vid[j]].vert.p; } } // Apply Normals Spherical correction for NPC head long neck_orgn = GetGroupOriginByName(eerie, "neck"); long head_idx = EERIE_OBJECT_GetGroup(eerie, "head"); if(head_idx >= 0 && neck_orgn >= 0) { VertexGroup & headGroup = eerie->grouplist[head_idx]; Vec3f center = Vec3f_ZERO; Vec3f origin = eerie->vertexlist[neck_orgn].v; float count = (float)headGroup.indexes.size(); if(count > 0.f) { for(size_t idx = 0 ; idx < headGroup.indexes.size(); idx++) { center += eerie->vertexlist[ headGroup.indexes[idx] ].v; } center = (center * (1.f / count) + origin + origin) * (1.0f / 3); float max_threshold = glm::distance(origin, center); for(size_t i = 0; i < headGroup.indexes.size(); i++) { EERIE_VERTEX * ev = &eerie->vertexlist[headGroup.indexes[i]]; float d = glm::distance(ev->v, origin); float factor = 1.f; if(d < max_threshold) { factor = d / max_threshold; } float ifactor = 1.f - factor; Vec3f fakenorm; fakenorm = ev->v - center; fakenorm = glm::normalize(fakenorm); ev->norm = ev->norm * ifactor + fakenorm * factor; ev->norm = glm::normalize(ev->norm); } } } // NORMALS CALCULATIONS END //*********************************************************** eerie->m_skeleton = NULL; EERIE_CreateCedricData(eerie); return eerie; }
//----------------------------------------------------------------------------- void CFireBall::Update(unsigned long aulTime) { ulCurrentTime += aulTime; if(ulCurrentTime > MIN_TIME_FIREBALL) { // smoke en retard pPSSmoke.SetPos(eCurPos); pPSSmoke.Update(aulTime); eCurPos += eMove * (aulTime * 0.0045f); pPSFire.SetPos(eCurPos); pPSFire.fParticleSpeed = 100; pPSFire.fParticleSpeedRandom = 200; pPSFire.p3ParticleGravity = -eMove * 2.f; pPSFire2.p3ParticleGravity = -eMove * 2.f; pPSFire2.SetPos(eCurPos); pPSFire2.fParticleSpeed = 100; pPSFire2.fParticleSpeedRandom = 100; } else { float afAlpha = 0.f; if (spells[spellinstance].caster == 0) { SetAngle(player.angle.b); afAlpha = player.angle.a; long idx = GetGroupOriginByName(entities[spells[spellinstance].caster]->obj, "chest"); if (idx) { eCurPos.x = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.x - fBetaRadSin * 60; eCurPos.y = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.y; eCurPos.z = entities[spells[spellinstance].caster]->obj->vertexlist3[idx].v.z + fBetaRadCos * 60; } else { eCurPos.x = player.pos.x - fBetaRadSin * 60; eCurPos.y = player.pos.y; eCurPos.z = player.pos.z + fBetaRadCos * 60; } } else { SetAngle(entities[spells[spellinstance].caster]->angle.b); eCurPos.x = entities[spells[spellinstance].caster]->pos.x - fBetaRadSin * 60; eCurPos.y = entities[spells[spellinstance].caster]->pos.y; eCurPos.z = entities[spells[spellinstance].caster]->pos.z + fBetaRadCos * 60; if ((ValidIONum(spells[spellinstance].caster)) && (entities[spells[spellinstance].caster]->ioflags & IO_NPC)) { eCurPos.x -= EEsin(radians(entities[spells[spellinstance].caster]->angle.b)) * 30.f; eCurPos.y -= 80.f; eCurPos.z += EEcos(radians(entities[spells[spellinstance].caster]->angle.b)) * 30.f; } Entity * io = entities[spells[spellinstance].caster]; if (ValidIONum(io->targetinfo)) { Vec3f * p1 = &eCurPos; Vec3f p2 = entities[io->targetinfo]->pos; p2.y -= 60.f; afAlpha = 360.f - (degrees(getAngle(p1->y, p1->z, p2.y, p2.z + dist(Vec2f(p2.x, p2.z), Vec2f(p1->x, p1->z))))); //alpha entre orgn et dest; } } eMove.x = - fBetaRadSin * 100 * cos(radians(MAKEANGLE(afAlpha))); eMove.y = sin(radians(MAKEANGLE(afAlpha))) * 100; eMove.z = + fBetaRadCos * 100 * cos(radians(MAKEANGLE(afAlpha))); Vec3f vMove = eMove.getNormalized(); // smoke en retard pPSSmoke.p3ParticleDirection = -vMove; pPSSmoke.SetPos(eCurPos); pPSSmoke.RecomputeDirection(); eCurPos = eCurPos + eMove * (aulTime * 0.0045f); pPSFire.p3ParticleDirection = -vMove; pPSFire.RecomputeDirection(); pPSFire.SetPos(eCurPos); pPSFire.p3ParticleGravity = -eMove * 2.f; pPSFire2.p3ParticleDirection = -vMove; pPSFire2.p3ParticleGravity = -eMove * 2.f; pPSFire2.RecomputeDirection(); pPSFire2.SetPos(eCurPos); } pPSFire.Update(aulTime); pPSFire2.Update(aulTime); }