void AddFixedObjectHalo(const EERIE_FACE & face, const TransformInfo & t, const Entity * io, TexturedVertex * tvList, const EERIE_3DOBJ * eobj) { float mdist=ACTIVECAM->cdepth; float ddist = mdist-fdist(t.pos, ACTIVECAM->orgTrans.pos); ddist = ddist/mdist; ddist = std::pow(ddist, 6); ddist = clamp(ddist, 0.25f, 0.9f); float tot=0; float _ffr[3]; for(long o = 0; o < 3; o++) { Vec3f temporary3D; temporary3D = t.rotation * eobj->vertexlist[face.vid[o]].norm; float power = 255.f-(float)EEfabs(255.f*(temporary3D.z)*( 1.0f / 2 )); power = clamp(power, 0.f, 255.f); tot += power; _ffr[o] = power; u8 lfr = io->halo.color.r * power; u8 lfg = io->halo.color.g * power; u8 lfb = io->halo.color.b * power; tvList[o].color = ((0xFF << 24) | (lfr << 16) | (lfg << 8) | (lfb)); } if(tot > 150.f) { long first; long second; long third; if(_ffr[0] >= _ffr[1] && _ffr[1] >= _ffr[2]) { first = 0; second = 1; third = 2; } else if(_ffr[0] >= _ffr[2] && _ffr[2] >= _ffr[1]) { first = 0; second = 2; third = 1; } else if(_ffr[1] >= _ffr[0] && _ffr[0] >= _ffr[2]) { first = 1; second = 0; third = 2; } else if(_ffr[1] >= _ffr[2] && _ffr[2] >= _ffr[0]) { first = 1; second = 2; third = 0; } else if(_ffr[2] >= _ffr[0] && _ffr[0] >= _ffr[1]) { first = 2; second = 0; third = 1; } else { first = 2; second = 1; third = 0; } if(_ffr[first] > 70.f && _ffr[second] > 60.f) { TexturedVertex vert[4]; vert[0] = tvList[first]; vert[1] = tvList[first]; vert[2] = tvList[second]; vert[3] = tvList[second]; float siz = ddist * (io->halo.radius * 1.5f * (EEsin(arxtime.get_frame_time() * .01f) * .1f + .7f)) * .6f; Vec3f vect1; vect1.x = tvList[first].p.x - tvList[third].p.x; vect1.y = tvList[first].p.y - tvList[third].p.y; float len1 = 1.f / ffsqrt(vect1.x * vect1.x + vect1.y * vect1.y); if(vect1.x < 0.f) len1 *= 1.2f; vect1.x *= len1; vect1.y *= len1; Vec3f vect2; vect2.x = tvList[second].p.x - tvList[third].p.x; vect2.y = tvList[second].p.y - tvList[third].p.y; float len2 = 1.f / ffsqrt(vect2.x * vect2.x + vect2.y * vect2.y); if(vect2.x < 0.f) len2 *= 1.2f; vect2.x *= len2; vect2.y *= len2; vert[1].p.x += (vect1.x + 0.2f - rnd() * 0.1f) * siz; vert[1].p.y += (vect1.y + 0.2f - rnd() * 0.1f) * siz; vert[1].color = 0xFF000000; vert[0].p.z += 0.0001f; vert[3].p.z += 0.0001f; vert[1].rhw *= .8f; vert[2].rhw *= .8f; vert[2].p.x += (vect2.x + 0.2f - rnd() * 0.1f) * siz; vert[2].p.y += (vect2.y + 0.2f - rnd() * 0.1f) * siz; if(io->halo.flags & HALO_NEGATIVE) vert[2].color = 0x00000000; else vert[2].color = 0xFF000000; Halo_AddVertices(vert); } } }
static void loadObjectData(EERIE_3DOBJ * eerie, const char * adr, size_t * poss, long version) { LogWarning << "loadObjectData"; size_t pos = *poss; const THEO_OFFSETS * to = reinterpret_cast<const THEO_OFFSETS *>(adr + pos); pos += sizeof(THEO_OFFSETS); const THEO_NB * tn = reinterpret_cast<const THEO_NB *>(adr + pos); LogDebug("Nb Vertex " << tn->nb_vertex << " Nb Action Points " << tn->nb_action_point << " Nb Lines " << tn->nb_lines); LogDebug("Nb Faces " << tn->nb_faces << " Nb Groups " << tn->nb_groups); eerie->vertexlist.resize(tn->nb_vertex); eerie->vertexlist3.resize(tn->nb_vertex); eerie->facelist.resize(tn->nb_faces); eerie->grouplist.resize(tn->nb_groups); eerie->actionlist.resize(tn->nb_action_point); eerie->ndata = NULL; eerie->pdata = NULL; eerie->cdata = NULL; eerie->sdata = NULL; // read vertices pos = to->vertex_seek; if(tn->nb_vertex > 65535) { LogError << ("Warning Vertex Number Too High..."); } for(long i = 0; i < tn->nb_vertex; i++) { const THEO_VERTEX * ptv = reinterpret_cast<const THEO_VERTEX *>(adr + pos); pos += sizeof(THEO_VERTEX); eerie->vertexlist[i].v = ptv->pos.toVec3(); eerie->cub.xmin = std::min(eerie->cub.xmin, ptv->pos.x); eerie->cub.xmax = std::max(eerie->cub.xmax, ptv->pos.x); eerie->cub.ymin = std::min(eerie->cub.ymin, ptv->pos.y); eerie->cub.ymax = std::max(eerie->cub.ymax, ptv->pos.y); eerie->cub.zmin = std::min(eerie->cub.zmin, ptv->pos.z); eerie->cub.zmax = std::max(eerie->cub.zmax, ptv->pos.z); } // Lecture des FACES THEO pos = to->faces_seek; for(long i = 0; i < tn->nb_faces; i++) { THEO_FACES_3006 tf3006; const THEO_FACES_3006 * ptf3006; if(version >= 3006) { ptf3006 = reinterpret_cast<const THEO_FACES_3006 *>(adr + pos); pos += sizeof(THEO_FACES_3006); } else { memset(&tf3006, 0, sizeof(THEO_FACES_3006)); const THEO_FACES * ptf = reinterpret_cast<const THEO_FACES *>(adr + pos); pos += sizeof(THEO_FACES); tf3006.color = ptf->color; tf3006.index1 = ptf->index1; tf3006.index2 = ptf->index2; tf3006.index3 = ptf->index3; tf3006.ismap = ptf->ismap; tf3006.liste_uv = ptf->liste_uv; tf3006.element_uv = ptf->element_uv; tf3006.num_map = ptf->num_map; tf3006.tile_x = ptf->tile_x; tf3006.tile_y = ptf->tile_y; tf3006.user_tile_x = ptf->user_tile_x; tf3006.user_tile_y = ptf->user_tile_y; tf3006.flag = ptf->flag; tf3006.collision_type = ptf->collision_type; tf3006.rgb = ptf->rgb; tf3006.rgb1 = ptf->rgb1; tf3006.rgb2 = ptf->rgb2; tf3006.rgb3 = ptf->rgb3; tf3006.double_side = ptf->double_side; tf3006.transparency = ptf->transparency; tf3006.trans = ptf->trans; ptf3006 = &tf3006; } eerie->facelist[i].vid[0] = (unsigned short)ptf3006->index1; eerie->facelist[i].vid[1] = (unsigned short)ptf3006->index2; eerie->facelist[i].vid[2] = (unsigned short)ptf3006->index3; s32 num_map = ((size_t)ptf3006->num_map >= eerie->texturecontainer.size()) ? -1 : ptf3006->num_map; if(ptf3006->ismap) { eerie->facelist[i].texid = (short)num_map; eerie->facelist[i].facetype = POLY_NO_SHADOW; if(num_map >= 0 && eerie->texturecontainer[num_map] && (eerie->texturecontainer[num_map]->userflags & POLY_NOCOL)) { eerie->facelist[i].facetype |= POLY_NOCOL; } } else { eerie->facelist[i].texid = -1; } switch(ptf3006->flag) { case 0: eerie->facelist[i].facetype |= POLY_GLOW; break; case 1: eerie->facelist[i].facetype |= POLY_NO_SHADOW; break; case 4: eerie->facelist[i].facetype |= POLY_METAL; break; case 10: eerie->facelist[i].facetype |= POLY_NOPATH; break; case 11: eerie->facelist[i].facetype |= POLY_CLIMB; break; case 12: eerie->facelist[i].facetype |= POLY_NOCOL; break; case 13: eerie->facelist[i].facetype |= POLY_NODRAW; break; case 14: eerie->facelist[i].facetype |= POLY_PRECISE_PATH; break; case 16: eerie->facelist[i].facetype |= POLY_NO_CLIMB; break; } eerie->facelist[i].ou[0] = (short)ptf3006->liste_uv.u1; eerie->facelist[i].ov[0] = (short)ptf3006->liste_uv.v1; eerie->facelist[i].ou[1] = (short)ptf3006->liste_uv.u2; eerie->facelist[i].ov[1] = (short)ptf3006->liste_uv.v2; eerie->facelist[i].ou[2] = (short)ptf3006->liste_uv.u3; eerie->facelist[i].ov[2] = (short)ptf3006->liste_uv.v3; if(ptf3006->double_side) { eerie->facelist[i].facetype |= POLY_DOUBLESIDED; } if(ptf3006->transparency > 0) { if(ptf3006->transparency == 2) { // NORMAL TRANS 0.00001 to 0.999999 if(ptf3006->trans < 1.f) { eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } } else if (ptf3006->transparency == 1) { if(ptf3006->trans < 0.f) { // SUBTRACTIVE -0.000001 to -0.999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } else { // ADDITIVE 1.000001 to 1.9999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans + 1.f; } } else { // MULTIPLICATIVE 2.000001 to 2.9999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans + 2.f; } } if(eerie->facelist[i].texid != -1 && !eerie->texturecontainer.empty() && eerie->texturecontainer[eerie->facelist[i].texid] != NULL) { if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_TRANS) { if(!(eerie->facelist[i].facetype & POLY_TRANS)) { eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_WATER) { eerie->facelist[i].facetype |= POLY_WATER; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_LAVA) { eerie->facelist[i].facetype |= POLY_LAVA; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_FALL) { eerie->facelist[i].facetype |= POLY_FALL; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_CLIMB) { eerie->facelist[i].facetype |= POLY_CLIMB; } } } // Groups Data pos = to->groups_seek; for(long i = 0; i < tn->nb_groups; i++) { THEO_GROUPS_3011 tg3011; const THEO_GROUPS_3011 * ptg3011; if(version >= 3011) { ptg3011 = reinterpret_cast<const THEO_GROUPS_3011 *>(adr + pos); pos += sizeof(THEO_GROUPS_3011); } else { const THEO_GROUPS * ltg = reinterpret_cast<const THEO_GROUPS *>(adr + pos); pos += sizeof(THEO_GROUPS); memset(&tg3011, 0, sizeof(THEO_GROUPS_3011)); tg3011.origin = ltg->origin; tg3011.nb_index = ltg->nb_index; ptg3011 = &tg3011; } eerie->grouplist[i].origin = ptg3011->origin; eerie->grouplist[i].indexes.resize(ptg3011->nb_index); std::copy((const long*)(adr + pos), (const long*)(adr + pos) + ptg3011->nb_index, eerie->grouplist[i].indexes.begin()); pos += ptg3011->nb_index * sizeof(long); eerie->grouplist[i].name = boost::to_lower_copy(util::loadString(adr + pos, 256)); pos += 256; eerie->grouplist[i].siz = 0.f; for(long o = 0; o < ptg3011->nb_index; o++) { eerie->grouplist[i].siz = std::max(eerie->grouplist[i].siz, fdist(eerie->vertexlist[eerie->grouplist[i].origin].v, eerie->vertexlist[eerie->grouplist[i].indexes[o]].v)); } eerie->grouplist[i].siz = ffsqrt(eerie->grouplist[i].siz) * (1.f/16); } // SELECTIONS s32 THEO_nb_selected = *reinterpret_cast<const s32 *>(adr + pos); pos += sizeof(s32); eerie->selections.resize(THEO_nb_selected); for(long i = 0; i < THEO_nb_selected; i++) { const THEO_SELECTED * pts = reinterpret_cast<const THEO_SELECTED *>(adr + pos); pos += sizeof(THEO_SELECTED); eerie->selections[i].name = boost::to_lower_copy(util::loadString(pts->name)); eerie->selections[i].selected.resize(pts->nb_index); if(pts->nb_index > 0) { std::copy((const long*)(adr + pos), (const long*)(adr + pos) + pts->nb_index, eerie->selections[i].selected.begin()); pos += sizeof(long) * pts->nb_index; } } // Theo Action Points Read pos = to->action_point_seek; for(long i = 0; i < tn->nb_action_point; i++) { const THEO_ACTION_POINT * ptap = reinterpret_cast<const THEO_ACTION_POINT *>(adr + pos); pos += sizeof(THEO_ACTION_POINT); eerie->actionlist[i].act = ptap->action; eerie->actionlist[i].sfx = ptap->num_sfx; eerie->actionlist[i].idx = ptap->vert_index; eerie->actionlist[i].name = boost::to_lower_copy(util::loadString(ptap->name)); } eerie->angle = Anglef::ZERO; eerie->pos = Vec3f_ZERO; // Now Interpret Extra Data chunk pos = to->extras_seek + 4; if(version >= 3005) { const THEO_EXTRA_DATA_3005 * pted3005 = reinterpret_cast<const THEO_EXTRA_DATA_3005 *>(adr + pos); pos += sizeof(THEO_EXTRA_DATA_3005); eerie->pos = pted3005->pos.toVec3(); eerie->angle.setYaw((float)(pted3005->angle.alpha & 0xfff) * THEO_ROTCONVERT); eerie->angle.setPitch((float)(pted3005->angle.beta & 0xfff) * THEO_ROTCONVERT); eerie->angle.setRoll((float)(pted3005->angle.gamma & 0xfff) * THEO_ROTCONVERT); eerie->point0 = eerie->vertexlist[pted3005->origin_index].v; eerie->origin = pted3005->origin_index; eerie->quat = pted3005->quat; } else { const THEO_EXTRA_DATA * pted = reinterpret_cast<const THEO_EXTRA_DATA *>(adr + pos); pos += sizeof(THEO_EXTRA_DATA); eerie->pos = pted->pos.toVec3(); eerie->angle.setYaw((float)(pted->angle.alpha & 0xfff) * THEO_ROTCONVERT); eerie->angle.setPitch((float)(pted->angle.beta & 0xfff) * THEO_ROTCONVERT); eerie->angle.setRoll((float)(pted->angle.gamma & 0xfff) * THEO_ROTCONVERT); eerie->point0 = eerie->vertexlist[pted->origin_index].v; eerie->origin = pted->origin_index; } *poss = pos; eerie->vertexlist3 = eerie->vertexlist; ReCreateUVs(eerie); EERIE_Object_Precompute_Fast_Access(eerie); }
// TODO copy-paste halo static void AddAnimatedObjectHalo(HaloInfo & haloInfo, const unsigned short * paf, float invisibility, EERIE_3DOBJ * eobj, Entity * io, TexturedVertex * tvList) { IO_HALO * curhalo = NULL; for(size_t h = 0; h < haloInfo.size; h++) { const HaloRenderInfo & entry = haloInfo.entries[h]; if(entry.selection == ObjSelection() || IsInSelection(eobj, paf[0], entry.selection)) { curhalo = entry.halo; break; } } if(!curhalo) return; float tot = 0; float _ffr[3]; ColorRGBA colors[3]; for(size_t o = 0; o < 3; o++) { float tttz = glm::abs(eobj->vertexlist3[paf[o]].norm.z) * ( 1.0f / 2 ); float power = 255.f - (float)(255.f * tttz); power *= (1.f - invisibility); power = glm::clamp(power, 0.f, 255.f); tot += power; _ffr[o] = power; u8 lfr = curhalo->color.r * power; u8 lfg = curhalo->color.g * power; u8 lfb = curhalo->color.b * power; colors[o] = Color(lfr, lfg, lfb, 255).toRGBA(); } if(tot > 260) { long first; long second; long third; if(_ffr[0] >= _ffr[1] && _ffr[1] >= _ffr[2]) { first = 0; second = 1; third = 2; } else if(_ffr[0] >= _ffr[2] && _ffr[2] >= _ffr[1]) { first = 0; second = 2; third = 1; } else if(_ffr[1] >= _ffr[0] && _ffr[0] >= _ffr[2]) { first = 1; second = 0; third = 2; } else if(_ffr[1] >= _ffr[2] && _ffr[2] >= _ffr[0]) { first = 1; second = 2; third = 0; } else if(_ffr[2] >= _ffr[0] && _ffr[0] >= _ffr[1]) { first = 2; second = 0; third = 1; } else { first = 2; second = 1; third = 0; } if(_ffr[first] > 150.f && _ffr[second] > 110.f) { TexturedVertex vert[4]; vert[0] = tvList[first]; vert[1] = tvList[first]; vert[2] = tvList[second]; vert[3] = tvList[second]; vert[0].color = colors[first]; vert[1].color = colors[first]; vert[2].color = colors[second]; vert[3].color = colors[second]; float siz = haloInfo.ddist * (curhalo->radius * (std::sin(arxtime.get_frame_time() * .01f) * .1f + 1.f)) * .6f; if(io == entities.player() && haloInfo.ddist > 0.8f && !EXTERNALVIEW) siz *= 1.5f; Vec3f vect1; vect1.x = tvList[first].p.x - tvList[third].p.x; vect1.y = tvList[first].p.y - tvList[third].p.y; float len1 = 2.f / ffsqrt(vect1.x * vect1.x + vect1.y * vect1.y); if(vect1.x < 0.f) len1 *= 1.2f; vect1.x *= len1; vect1.y *= len1; Vec3f vect2; vect2.x = tvList[second].p.x - tvList[third].p.x; vect2.y = tvList[second].p.y - tvList[third].p.y; float len2 = 1.f / ffsqrt(vect2.x * vect2.x + vect2.y * vect2.y); if(vect2.x < 0.f) len2 *= 1.2f; vect2.x *= len2; vect2.y *= len2; vert[1].p.x += (vect1.x + Random::getf(0.1f, 0.2f)) * siz; vert[1].p.y += (vect1.y + Random::getf(0.1f, 0.2f)) * siz; vert[1].color = Color(0, 0, 0, 255).toRGBA(); float valll; valll = 0.005f + (glm::abs(tvList[first].p.z) - glm::abs(tvList[third].p.z)) + (glm::abs(tvList[second].p.z) - glm::abs(tvList[third].p.z)); valll = 0.0001f + valll * ( 1.0f / 10 ); if(valll < 0.f) valll = 0.f; vert[1].p.z += valll; vert[2].p.z += valll; vert[0].p.z += 0.0001f; vert[3].p.z += 0.0001f;//*( 1.0f / 2 ); vert[1].rhw *= .98f; vert[2].rhw *= .98f; vert[0].rhw *= .98f; vert[3].rhw *= .98f; vert[2].p.x += (vect2.x + Random::getf(0.1f, 0.2f)) * siz; vert[2].p.y += (vect2.y + Random::getf(0.1f, 0.2f)) * siz; vert[1].p.z = (vert[1].p.z + haloInfo.MAX_ZEDE) * ( 1.0f / 2 ); vert[2].p.z = (vert[2].p.z + haloInfo.MAX_ZEDE) * ( 1.0f / 2 ); if(curhalo->flags & HALO_NEGATIVE) vert[2].color = Color(0, 0, 0, 0).toRGBA(); else vert[2].color = Color(0, 0, 0, 255).toRGBA(); Halo_AddVertices(vert); } } }