bool CylinderAboveInvalidZone(EERIE_CYLINDER * cyl) { float count = 0; float failcount = 0; for (float rad = 0; rad < cyl->radius; rad += 10.f) for (float ang = 0; ang < 360; ang += 45) { if (rad == 0) ang = 360; EERIE_3D pos; pos.x = cyl->origin.x - EEsin(DEG2RAD(ang)) * rad; pos.y = cyl->origin.y - 20.f; pos.z = cyl->origin.z + EEcos(DEG2RAD(ang)) * rad; EERIEPOLY * ep = ANCHOR_CheckInPoly(pos.x, pos.y, pos.z); if (!ep) continue; if (ep->type & POLY_NOPATH) return true; count += 1.f; float vy; GetTruePolyY(ep, &pos, &vy); if (EEfabs(vy - cyl->origin.y) > 160.f) failcount++; } float failratio = failcount / count; if (failratio > 0.75f) return true; return false; }
void DrawEERIEInter_Render(EERIE_3DOBJ *eobj, const TransformInfo &t, Entity *io, float invisibility) { ColorMod colorMod; colorMod.updateFromEntity(io, !io); Vec3f tv = t.pos; if(io && (io->ioflags & IO_ITEM)) tv.y -= 60.f; else tv.y -= 90.f; UpdateLlights(tv, false); for(size_t i = 0; i < eobj->facelist.size(); i++) { const EERIE_FACE & face = eobj->facelist[i]; if(CullFace(eobj, face)) continue; if(face.texid < 0) continue; TextureContainer *pTex = eobj->texturecontainer[face.texid]; if(!pTex) continue; float fTransp = 0.f; TexturedVertex *tvList = GetNewVertexList(pTex, face, invisibility, fTransp); for(size_t n = 0; n < 3; n++) { if(io && (io->ioflags & IO_ANGULAR)) { const Vec3f & position = eobj->vertexlist3[face.vid[n]].v; const Vec3f & normal = face.norm; eobj->vertexlist3[face.vid[n]].vert.color = ApplyLight(&t.rotation, position, normal, colorMod, 0.5f); } else { Vec3f & position = eobj->vertexlist3[face.vid[n]].v; Vec3f & normal = eobj->vertexlist[face.vid[n]].norm; eobj->vertexlist3[face.vid[n]].vert.color = ApplyLight(&t.rotation, position, normal, colorMod); } tvList[n] = eobj->vertexlist[face.vid[n]].vert; tvList[n].uv.x = face.u[n]; tvList[n].uv.y = face.v[n]; // Treat WATER Polys (modify UVs) if(face.facetype & POLY_WATER) { tvList[n].uv += getWaterFxUvOffset(eobj->vertexlist[face.vid[n]].v, 0.3f); } if(face.facetype & POLY_GLOW) { // unaffected by light tvList[n].color = 0xffffffff; } else { // Normal Illuminations tvList[n].color = eobj->vertexlist3[face.vid[n]].vert.color; } // TODO copy-paste if(io && Project.improve) { long lr=(tvList[n].color>>16) & 255; float ffr=(float)(lr); float dd = tvList[n].rhw; dd = clamp(dd, 0.f, 1.f); Vec3f & norm = eobj->vertexlist[face.vid[n]].norm; float fb=((1.f-dd)*6.f + (EEfabs(norm.x) + EEfabs(norm.y))) * 0.125f; float fr=((.6f-dd)*6.f + (EEfabs(norm.z) + EEfabs(norm.y))) * 0.125f; if(fr < 0.f) fr = 0.f; else fr = std::max(ffr, fr * 255.f); fr=std::min(fr,255.f); fb*=255.f; fb=std::min(fb,255.f); u8 lfr = fr; u8 lfb = fb; u8 lfg = 0x1E; tvList[n].color = (0xff000000L | (lfr << 16) | (lfg << 8) | (lfb)); } // Transparent poly: storing info to draw later if((face.facetype & POLY_TRANS) || invisibility > 0.f) { tvList[n].color = Color::gray(fTransp).toBGR(); } } // HALO HANDLING START if(io && (io->halo.flags & HALO_ACTIVE)) { AddFixedObjectHalo(face, t, io, tvList, eobj); } }
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); } } }
//*********************************************************************************************** // hum... to be checked again for performance and result quality. //----------------------------------------------------------------------------------------------- // VERIFIED (Cyril 2001/10/15) //*********************************************************************************************** void ARXDRAW_DrawInterShadows(LPDIRECT3DDEVICE7 pd3dDevice) { bool bNoVB = false; if( bSoftRender ) { bNoVB = GET_FORCE_NO_VB(); SET_FORCE_NO_VB( true ); } GDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,0); SetZBias(pd3dDevice,1); long k; long first=1; for (long i=0;i<TREATZONE_CUR;i++) { if ((treatio[i].show!=1) || (treatio[i].io==NULL)) continue; INTERACTIVE_OBJ * io=treatio[i].io; if ( (!io->obj) || (io->ioflags & IO_JUST_COLLIDE) ) { continue; } if ((Project.hide & HIDE_NPC) && (io->ioflags & IO_NPC)) continue; if ((Project.hide & HIDE_ITEMS) && (io->ioflags & IO_ITEM)) continue; if ((Project.hide & HIDE_FIXINTER) && (io->ioflags & IO_FIX)) continue; long xx,yy; F2L((io->pos.x)*ACTIVEBKG->Xmul,&xx); F2L((io->pos.z)*ACTIVEBKG->Zmul,&yy); if ( (xx>=1) && (yy>=1) && (xx<ACTIVEBKG->Xsize-1) && (yy<ACTIVEBKG->Zsize-1) ) { FAST_BKG_DATA * feg=(FAST_BKG_DATA *)&ACTIVEBKG->fastdata[xx][yy]; if(!feg->treat) continue; } if (!( io->ioflags & IO_NOSHADOW ) ) if ( io->show==SHOW_FLAG_IN_SCENE ) if ( !(io->ioflags & IO_GOLD) ) { register EERIEPOLY * ep; D3DTLVERTEX in; D3DTLVERTEX ltv[4]; ltv[0]= D3DTLVERTEX( D3DVECTOR( 0, 0, 0.001f ), 1.f, 0, 1, 0.3f, 0.3f) ; ltv[1]= D3DTLVERTEX( D3DVECTOR( 0, 0, 0.001f ), 1.f, 0, 1, 0.7f, 0.3f) ; ltv[2]= D3DTLVERTEX( D3DVECTOR( 0, 0, 0.001f ), 1.f, 0, 1, 0.7f, 0.7f) ; ltv[3]= D3DTLVERTEX( D3DVECTOR( 0, 0, 0.001f ), 1.f, 0, 1, 0.3f, 0.7f) ; float s1=16.f*io->scale; float s2=s1 * DIV2; if (io->obj->nbgroups<=1) { for (k=0;k<io->obj->nbvertex;k+=9) { ep=EECheckInPoly(&io->obj->vertexlist3[k].v); if (ep!=NULL) { in.sy=ep->min.y-3.f; float r=0.5f-((float)EEfabs(io->obj->vertexlist3[k].v.y-in.sy))*DIV500; r-=io->invisibility; r*=io->scale; if (r<=0.f) continue; in.sx=io->obj->vertexlist3[k].v.x-s2; in.sz=io->obj->vertexlist3[k].v.z-s2; long lv; r*=255.f; F2L(r,&lv); ltv[0].color=ltv[1].color=ltv[2].color=ltv[3].color=0xFF000000 | lv<<16 | lv<<8 | lv; if (first) { first=0; SETZWRITE(pd3dDevice, FALSE ); SETBLENDMODE(pd3dDevice,D3DBLEND_ZERO,D3DBLEND_INVSRCCOLOR); SETALPHABLEND(pd3dDevice,TRUE); SETTC(pd3dDevice,Boom); } EE_RT2(&in,<v[0]); in.sx+=s1; EE_RT2(&in,<v[1]); in.sz+=s1; EE_RT2(&in,<v[2]); in.sx-=s1; EE_RT2(&in,<v[3]); if ((ltv[0].sz>0.f) && (ltv[1].sz>0.f) && (ltv[2].sz>0.f)) { ARX_DrawPrimitive_SoftClippZ( <v[0], <v[1], <v[2], 50.f); ARX_DrawPrimitive_SoftClippZ( <v[0], <v[2], <v[3], 50.f); } } } } else { for (k=0;k<io->obj->nbgroups;k++) { long origin=io->obj->grouplist[k].origin; ep=EECheckInPoly( &io->obj->vertexlist3[origin].v ); if (ep!=NULL) { in.sy=ep->min.y-3.f; float r=0.8f-((float)EEfabs(io->obj->vertexlist3[origin].v.y-in.sy))*DIV500; r*=io->obj->grouplist[k].siz; r-=io->invisibility; if (r<=0.f) continue; float s1=io->obj->grouplist[k].siz*44.f; float s2=s1*DIV2; in.sx=io->obj->vertexlist3[origin].v.x-s2; in.sz=io->obj->vertexlist3[origin].v.z-s2; long lv; r*=255.f; F2L(r,&lv); ltv[0].color= ltv[1].color = ltv[2].color = ltv[3].color = 0xFF000000 | lv<<16 | lv<<8 | lv; if (first) { first=0; SETZWRITE(pd3dDevice, FALSE ); SETBLENDMODE(pd3dDevice,D3DBLEND_ZERO,D3DBLEND_INVSRCCOLOR); SETALPHABLEND(pd3dDevice,TRUE); SETTC(pd3dDevice,Boom); } EE_RT2(&in,<v[0]); in.sx+=s1; EE_RT2(&in,<v[1]); in.sz+=s1; EE_RT2(&in,<v[2]); in.sx-=s1; EE_RT2(&in,<v[3]); ARX_DrawPrimitive_SoftClippZ( <v[0], <v[1], <v[2], 50.f); ARX_DrawPrimitive_SoftClippZ( <v[0], <v[2], <v[3], 50.f); } } } } } SETALPHABLEND(pd3dDevice,FALSE); SETZWRITE(pd3dDevice, TRUE ); SetZBias(pd3dDevice,0); GDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,ulBKGColor); if( bSoftRender ) SET_FORCE_NO_VB( bNoVB ); }
void AnchorData_Create_Links_Original_Method(EERIE_BACKGROUND * eb) { EERIE_BKG_INFO * eg; EERIE_BKG_INFO * eg2; long ii, ia, ji, ja; EERIE_3D p1, p2; char text[256]; long count = 0; long per; long lastper = -1; long total = eb->Zsize * eb->Xsize; for (long j = 0; j < eb->Zsize; j++) for (long i = 0; i < eb->Xsize; i++) { F2L((float)count / (float)total * 100.f, &per); if (per != lastper) { sprintf(text, "Anchor Links Generation: %d%%", per); lastper = per; _ShowText(text); } danaeApp.WinManageMess(); count++; eg = &eb->Backg[i+j*eb->Xsize]; long precise = 0; for (long kkk = 0; kkk < eg->nbpolyin; kkk++) { EERIEPOLY * ep = eg->polyin[kkk]; if (ep->type & POLY_PRECISE_PATH) { precise = 1; break; } } for (long k = 0; k < eg->nbianchors; k++) { ii = i - 2; ia = i + 2; ji = j - 2; ja = j + 2; FORCERANGE(ii, 0, eb->Xsize - 1); FORCERANGE(ia, 0, eb->Xsize - 1); FORCERANGE(ji, 0, eb->Zsize - 1); FORCERANGE(ja, 0, eb->Zsize - 1); for (long j2 = ji; j2 <= ja; j2++) for (long i2 = ii; i2 <= ia; i2++) { eg2 = &eb->Backg[i2+j2*eb->Xsize]; long precise2 = 0; for (long kkk = 0; kkk < eg2->nbpolyin; kkk++) { EERIEPOLY * ep2 = eg2->polyin[kkk]; if (ep2->type & POLY_PRECISE_PATH) { precise2 = 1; break; } } for (long k2 = 0; k2 < eg2->nbianchors; k2++) { // don't treat currently treated anchor if (eg->ianchors[k] == eg2->ianchors[k2]) continue; memcpy(&p1, &eb->anchors[eg->ianchors[k]].pos, sizeof(EERIE_3D)); memcpy(&p2, &eb->anchors[eg2->ianchors[k2]].pos, sizeof(EERIE_3D)); p1.y += 10.f; p2.y += 10.f; long _onetwo = 0; BOOL treat = TRUE; float dist = TRUEEEDistance3D(&p1, &p2); float dd = TRUEDistance2D(p1.x, p1.z, p2.x, p2.z); if (dd < 5.f) continue; if (dd > 200.f) continue; if (precise || precise2) { if (dist > 120.f) continue; } else if (dist > 200.f) continue; if (EEfabs(p1.y - p2.y) > dd * 0.9f) continue; IO_PHYSICS ip; ip.startpos.x = ip.cyl.origin.x = p1.x; ip.startpos.y = ip.cyl.origin.y = p1.y; ip.startpos.z = ip.cyl.origin.z = p1.z; ip.targetpos.x = p2.x; ip.targetpos.y = p2.y; ip.targetpos.z = p2.z; ip.cyl.height = eb->anchors[eg->ianchors[k]].height; ip.cyl.radius = eb->anchors[eg->ianchors[k]].radius; EERIE_3D vect; vect.x = p2.x - p1.x; vect.y = p2.y - p1.y; vect.z = p2.z - p1.z; long t = 2; if (ANCHOR_ARX_COLLISION_Move_Cylinder(&ip, NULL, 20, CFLAG_CHECK_VALID_POS | CFLAG_NO_INTERCOL | CFLAG_EASY_SLIDING | CFLAG_NPC | CFLAG_JUST_TEST | CFLAG_EXTRA_PRECISION)) //CFLAG_SPECIAL { if (TRUEDistance2D(ip.cyl.origin.x, ip.cyl.origin.z, ip.targetpos.x, ip.targetpos.z) > 25) t--; else _onetwo = 1; } else t--; if (t == 1) { ip.startpos.x = ip.cyl.origin.x = p2.x; ip.startpos.y = ip.cyl.origin.y = p2.y; ip.startpos.z = ip.cyl.origin.z = p2.z; ip.targetpos.x = p1.x; ip.targetpos.y = p1.y; ip.targetpos.z = p1.z; ip.cyl.height = eb->anchors[eg2->ianchors[k2]].height; ip.cyl.radius = eb->anchors[eg2->ianchors[k2]].radius; if (ANCHOR_ARX_COLLISION_Move_Cylinder(&ip, NULL, 20, CFLAG_CHECK_VALID_POS | CFLAG_NO_INTERCOL | CFLAG_EASY_SLIDING | CFLAG_NPC | CFLAG_JUST_TEST | CFLAG_EXTRA_PRECISION | CFLAG_RETURN_HEIGHT)) //CFLAG_SPECIAL { if (TRUEDistance2D(ip.cyl.origin.x, ip.cyl.origin.z, ip.targetpos.x, ip.targetpos.z) > 25) t--; else _onetwo |= 2; } else t--; } else t--; if (t <= 0) treat = FALSE; else treat = TRUE; if (treat) { if (_onetwo) { AddAnchorLink(eb, eg->ianchors[k], eg2->ianchors[k2]); AddAnchorLink(eb, eg2->ianchors[k2], eg->ianchors[k]); } } } } } } EERIE_PATHFINDER_Create(eb); }
bool AddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, EERIE_3D * pos, long flags) { long found = 0; long best = 0; long stop_radius = 0; float best_dist = 99999999999.f; float v_dist = 99999999999.f; EERIE_CYLINDER testcyl; EERIE_CYLINDER currcyl; EERIE_CYLINDER bestcyl; bestcyl.height = 0; bestcyl.radius = 0; for (long rad = 0; rad < 20; rad += 10) for (long ang = 0; ang < 360; ang += 45) // 45 { float t = DEG2RAD((float)ang); // We set our current position depending on given position, radius & angle. currcyl.radius = 40; currcyl.height = -165; currcyl.origin.x = pos->x - EEsin(t) * (float)rad; currcyl.origin.y = pos->y; currcyl.origin.z = pos->z + EEcos(t) * (float)rad; stop_radius = 0; found = 0; long climb = 0; while ((stop_radius != 1)) { memcpy(&testcyl, &currcyl, sizeof(EERIE_CYLINDER)); testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(&testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (EEfabs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if (found) { float dist = TRUEEEDistance3D(pos, &currcyl.origin); float vd = EEfabs(pos->y - currcyl.origin.y); if (currcyl.radius >= bestcyl.radius) { if (((best_dist > dist) && (currcyl.radius == bestcyl.radius)) || (currcyl.radius > bestcyl.radius)) { memcpy(&bestcyl, &currcyl, sizeof(EERIE_CYLINDER)); best_dist = dist; v_dist = vd; best = 1; } } } } if (!best) return FALSE; if (CylinderAboveInvalidZone(&bestcyl)) return FALSE; if (flags == MUST_BE_BIG) { if (bestcyl.radius < 60) return FALSE; } // avoid to recreate same anchor twice... if (0) for (long k = 0; k < eb->nbanchors; k++) { _ANCHOR_DATA * ad = &eb->anchors[k]; if ((ad->pos.x == bestcyl.origin.x) && (ad->pos.y == bestcyl.origin.y) && (ad->pos.z == bestcyl.origin.z)) { if (ad->radius >= bestcyl.radius) return FALSE; if (ad->radius <= bestcyl.radius) { ad->height = bestcyl.height; ad->radius = bestcyl.radius; return FALSE; } } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); if (!eg->ianchors) HERMES_Memory_Emergency_Out(); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (_ANCHOR_DATA *)realloc(eb->anchors, sizeof(_ANCHOR_DATA) * (eb->nbanchors + 1)); if (!eb->anchors) HERMES_Memory_Emergency_Out(); _ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos.x = bestcyl.origin.x; ad->pos.y = bestcyl.origin.y; ad->pos.z = bestcyl.origin.z; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return TRUE; }
bool DirectAddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, EERIE_3D * pos, long flags) { long found = 0; long best = 0; long stop_radius = 0; float best_dist = 99999999999.f; float v_dist = 99999999999.f; EERIE_CYLINDER testcyl; EERIE_CYLINDER currcyl; EERIE_CYLINDER bestcyl; bestcyl.height = 0; bestcyl.radius = 0; currcyl.radius = 40; currcyl.height = -165.f; currcyl.origin.x = pos->x; currcyl.origin.y = pos->y; currcyl.origin.z = pos->z; stop_radius = 0; found = 0; long climb = 0; while (stop_radius != 1) { memcpy(&testcyl, &currcyl, sizeof(EERIE_CYLINDER)); testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(&testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (EEfabs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if (found) { float dist = TRUEEEDistance3D(pos, &currcyl.origin); float vd = EEfabs(pos->y - currcyl.origin.y); if ((currcyl.radius >= bestcyl.radius)) { if (((best_dist > dist) && (currcyl.radius == bestcyl.radius)) || (currcyl.radius > bestcyl.radius)) { memcpy(&bestcyl, &currcyl, sizeof(EERIE_CYLINDER)); best_dist = dist; v_dist = vd; best = 1; } } } if (!best) return FALSE; if (CylinderAboveInvalidZone(&bestcyl)) return FALSE; for (long k = 0; k < eb->nbanchors; k++) { _ANCHOR_DATA * ad = &eb->anchors[k]; if (TRUEEEDistance3D(&ad->pos, &bestcyl.origin) < 50.f) return FALSE; if (TRUEDistance2D(ad->pos.x, ad->pos.z, bestcyl.origin.x, bestcyl.origin.z) < 45.f) { if (EEfabs(ad->pos.y - bestcyl.origin.y) < 90.f) return FALSE; EERIEPOLY * ep = ANCHOR_CheckInPolyPrecis(ad->pos.x, ad->pos.y, ad->pos.z); EERIEPOLY * ep2 = ANCHOR_CheckInPolyPrecis(ad->pos.x, bestcyl.origin.y, ad->pos.z); if (ep2 == ep) return FALSE; } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); if (!eg->ianchors) HERMES_Memory_Emergency_Out(); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (_ANCHOR_DATA *)realloc(eb->anchors, sizeof(_ANCHOR_DATA) * (eb->nbanchors + 1)); if (!eb->anchors) HERMES_Memory_Emergency_Out(); _ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos.x = bestcyl.origin.x; ad->pos.y = bestcyl.origin.y; ad->pos.z = bestcyl.origin.z; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return TRUE; }
BOOL ANCHOR_AttemptValidCylinderPos(EERIE_CYLINDER * cyl, INTERACTIVE_OBJ * io, long flags) { float anything = ANCHOR_CheckAnythingInCylinder(cyl, io, flags); if ((flags & CFLAG_LEVITATE) && (anything == 0.f)) return TRUE; if (anything >= 0.f) // Falling Cylinder but valid pos ! { if (flags & CFLAG_RETURN_HEIGHT) cyl->origin.y += anything; return TRUE; } EERIE_CYLINDER tmp; if (!(flags & CFLAG_ANCHOR_GENERATION)) { memcpy(&tmp, cyl, sizeof(EERIE_CYLINDER)); while (anything < 0.f) { tmp.origin.y += anything; anything = ANCHOR_CheckAnythingInCylinder(&tmp, io, flags); } anything = tmp.origin.y - cyl->origin.y; } if (MOVING_CYLINDER) { if (flags & CFLAG_NPC) { float tolerate; if ((io) && (io->ioflags & IO_NPC) && (io->_npcdata->pathfind.listnb > 0) && (io->_npcdata->pathfind.listpos < io->_npcdata->pathfind.listnb)) { tolerate = -80; } else tolerate = -45; if (anything < tolerate) return FALSE; } if (io && (!(flags & CFLAG_JUST_TEST))) { if ((flags & CFLAG_PLAYER) && (anything < 0.f)) { if (player.jumpphase) { io->_npcdata->climb_count = MAX_ALLOWED_PER_SECOND; return FALSE; } float dist; dist = __max(TRUEVector_Magnitude(&vector2D), 1.f); float pente; pente = EEfabs(anything) / dist * DIV2; io->_npcdata->climb_count += pente; if (io->_npcdata->climb_count > MAX_ALLOWED_PER_SECOND) { io->_npcdata->climb_count = MAX_ALLOWED_PER_SECOND; return FALSE; } if (anything < -55) { io->_npcdata->climb_count = MAX_ALLOWED_PER_SECOND; return FALSE; } } } } else if (anything < -45) return FALSE; if ((flags & CFLAG_SPECIAL) && (anything < -40)) { if (flags & CFLAG_RETURN_HEIGHT) cyl->origin.y += anything; return FALSE; } memcpy(&tmp, cyl, sizeof(EERIE_CYLINDER)); tmp.origin.y += anything; anything = ANCHOR_CheckAnythingInCylinder(&tmp, io, flags); if (anything < 0.f) { if (flags & CFLAG_RETURN_HEIGHT) { while (anything < 0.f) { tmp.origin.y += anything; anything = ANCHOR_CheckAnythingInCylinder(&tmp, io, flags); } cyl->origin.y = tmp.origin.y; } return FALSE; } cyl->origin.y = tmp.origin.y; return TRUE; }
void FlareLine(const Vec2s & pos0, const Vec2s & pos1, Entity * io) { float m; long i; long z; float x0 = pos0.x; float x1 = pos1.x; float y0 = pos0.y; float y1 = pos1.y; float dx = (x1 - x0); float adx = EEfabs(dx); float dy = (y1 - y0); float ady = EEfabs(dy); if(adx > ady) { if(x0 > x1) { z = x1; x1 = x0; x0 = z; z = y1; y0 = z; } if(x0 < x1) { m = dy / dx; i = x0; while(i < x1) { z = rnd() * FLARELINERND; z += FLARELINESTEP; i += z; y0 += m * z; AddLFlare(Vec2s(i, y0), io); } } else { m = dy / dx; i = x1; while(i < x0) { z = rnd() * FLARELINERND; z += FLARELINESTEP; i += z; y0 += m * z; AddLFlare(Vec2s(i, y0), io); } } } else { if(y0 > y1) { z = x1; x0 = z; z = y1; y1 = y0; y0 = z; } if(y0 < y1) { m = dx / dy; i = y0; while(i < y1) { z = rnd() * FLARELINERND; z += FLARELINESTEP; i += z; x0 += m * z; AddLFlare(Vec2s(x0, i), io); } } else { m = dx / dy; i = y1; while(i < y0) { z = rnd() * FLARELINERND; z += FLARELINESTEP; i += z; x0 += m * z; AddLFlare(Vec2s(x0, i), io); } } } }
void ARXDRAW_DrawInterShadows() { GRenderer->SetFogColor(Color::none); SetZBias(1); long first=1; for(long i=0; i<TREATZONE_CUR; i++) { if(treatio[i].show != 1 || !treatio[i].io) continue; Entity *io = treatio[i].io; if(!io->obj || (io->ioflags & IO_JUST_COLLIDE)) continue; FAST_BKG_DATA * bkgData = getFastBackgroundData(io->pos.x, io->pos.z); if(bkgData && !bkgData->treat) { //TODO is that correct ? continue; } if(!(io->ioflags & IO_NOSHADOW) && io->show==SHOW_FLAG_IN_SCENE && !(io->ioflags & IO_GOLD)) { TexturedVertex in; TexturedVertex ltv[4]; ltv[0] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, 0, 1, Vec2f(0.3f, 0.3f)); ltv[1] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, 0, 1, Vec2f(0.7f, 0.3f)); ltv[2] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, 0, 1, Vec2f(0.7f, 0.7f)); ltv[3] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, 0, 1, Vec2f(0.3f, 0.7f)); if(io->obj->nbgroups <= 1) { for(size_t k=0; k < io->obj->vertexlist.size(); k += 9) { EERIEPOLY *ep = EECheckInPoly(&io->obj->vertexlist3[k].v); if(ep) { in.p.y=ep->min.y-3.f; float r=0.5f-((float)EEfabs(io->obj->vertexlist3[k].v.y-in.p.y))*( 1.0f / 500 ); r-=io->invisibility; r*=io->scale; if(r<=0.f) continue; float s1=16.f*io->scale; float s2=s1*( 1.0f / 2 ); in.p.x=io->obj->vertexlist3[k].v.x-s2; in.p.z=io->obj->vertexlist3[k].v.z-s2; r*=255.f; long lv = r; ltv[0].color=ltv[1].color=ltv[2].color=ltv[3].color=0xFF000000 | lv<<16 | lv<<8 | lv; if(first) { first=0; GRenderer->SetRenderState(Renderer::DepthWrite, false); GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor); GRenderer->SetRenderState(Renderer::AlphaBlending, true); GRenderer->SetTexture(0, Boom); } EE_RT2(&in,<v[0]); in.p.x+=s1; EE_RT2(&in,<v[1]); in.p.z+=s1; EE_RT2(&in,<v[2]); in.p.x-=s1; EE_RT2(&in,<v[3]); if(ltv[0].p.z > 0.f && ltv[1].p.z > 0.f && ltv[2].p.z > 0.f) { ARX_DrawPrimitive(<v[0], <v[1], <v[2], 50.0f); ARX_DrawPrimitive(<v[0], <v[2], <v[3], 50.0f); } } } } else { for(long k = 0; k < io->obj->nbgroups; k++) { long origin=io->obj->grouplist[k].origin; EERIEPOLY *ep = EECheckInPoly(&io->obj->vertexlist3[origin].v); if(ep) { in.p.y=ep->min.y-3.f; float r=0.8f-((float)EEfabs(io->obj->vertexlist3[origin].v.y-in.p.y))*( 1.0f / 500 ); r*=io->obj->grouplist[k].siz; r-=io->invisibility; if(r<=0.f) continue; float s1=io->obj->grouplist[k].siz*44.f; float s2=s1*( 1.0f / 2 ); in.p.x=io->obj->vertexlist3[origin].v.x-s2; in.p.z=io->obj->vertexlist3[origin].v.z-s2; r*=255.f; long lv = r; ltv[0].color=ltv[1].color=ltv[2].color=ltv[3].color=0xFF000000 | lv<<16 | lv<<8 | lv; if(first) { first=0; GRenderer->SetRenderState(Renderer::DepthWrite, false); GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor); GRenderer->SetRenderState(Renderer::AlphaBlending, true); GRenderer->SetTexture(0, Boom); } EE_RT2(&in,<v[0]); in.p.x+=s1; EE_RT2(&in,<v[1]); in.p.z+=s1; EE_RT2(&in,<v[2]); in.p.x-=s1; EE_RT2(&in,<v[3]); ARX_DrawPrimitive(<v[0], <v[1], <v[2]); ARX_DrawPrimitive(<v[0], <v[2], <v[3]); } } } } } GRenderer->SetRenderState(Renderer::AlphaBlending, false); GRenderer->SetRenderState(Renderer::DepthWrite, true); SetZBias(0); GRenderer->SetFogColor(ulBKGColor); }
// Creation of the physics box... quite cabalistic and extensive func... // Need to put a (really) smarter algorithm in there... void EERIE_PHYSICS_BOX_Create(EERIE_3DOBJ * obj) { if (!obj) return; EERIE_PHYSICS_BOX_Release(obj); if (obj->nbvertex == 0) return; obj->pbox = (PHYSICS_BOX_DATA *) malloc(sizeof(PHYSICS_BOX_DATA)); memset(obj->pbox, 0, sizeof(PHYSICS_BOX_DATA)); obj->pbox->nb_physvert = 15; obj->pbox->stopcount = 0; obj->pbox->vert = (PHYSVERT *) malloc(sizeof(PHYSVERT) * obj->pbox->nb_physvert); memset(obj->pbox->vert, 0, sizeof(PHYSVERT)*obj->pbox->nb_physvert); EERIE_3D cubmin, cubmax; cubmin.x = FLT_MAX; cubmin.y = FLT_MAX; cubmin.z = FLT_MAX; cubmax.x = -FLT_MAX; cubmax.y = -FLT_MAX; cubmax.z = -FLT_MAX; for (long k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; cubmin.x = __min(cubmin.x, obj->vertexlist[k].v.x); cubmin.y = __min(cubmin.y, obj->vertexlist[k].v.y); cubmin.z = __min(cubmin.z, obj->vertexlist[k].v.z); cubmax.x = __max(cubmax.x, obj->vertexlist[k].v.x); cubmax.y = __max(cubmax.y, obj->vertexlist[k].v.y); cubmax.z = __max(cubmax.z, obj->vertexlist[k].v.z); } obj->pbox->vert[0].pos.x = cubmin.x + (cubmax.x - cubmin.x) * DIV2; obj->pbox->vert[0].pos.y = cubmin.y + (cubmax.y - cubmin.y) * DIV2; obj->pbox->vert[0].pos.z = cubmin.z + (cubmax.z - cubmin.z) * DIV2; obj->pbox->vert[13].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[13].pos.y = cubmin.y; obj->pbox->vert[13].pos.z = obj->pbox->vert[0].pos.z; obj->pbox->vert[14].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[14].pos.y = cubmax.y; obj->pbox->vert[14].pos.z = obj->pbox->vert[0].pos.z; for (int k = 1; k < obj->pbox->nb_physvert - 2; k++) { obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z; if (k < 5) obj->pbox->vert[k].pos.y = cubmin.y; else if (k < 9) obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y; else obj->pbox->vert[k].pos.y = cubmax.y; } float diff = cubmax.y - cubmin.y; if (diff < 12.f) { cubmax.y += 8.f; cubmin.y -= 8.f; for (int k = 1; k < obj->pbox->nb_physvert - 2; k++) { obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z; if (k < 5) obj->pbox->vert[k].pos.y = cubmin.y; else if (k < 9) obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y; else obj->pbox->vert[k].pos.y = cubmax.y; } obj->pbox->vert[14].pos.y = cubmax.y; obj->pbox->vert[13].pos.y = cubmin.y; float RATI = diff * DIV8; for (int k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; EERIE_3D curr; memcpy(&curr, &obj->vertexlist[k].v, sizeof(EERIE_3D)); long SEC = 1; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); SEC = 5; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x - RATI); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z - RATI); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x - RATI); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z + RATI); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x + RATI); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z + RATI); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x + RATI); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z - RATI); SEC = 9; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); } } else { float cut = (cubmax.y - cubmin.y) * DIV3; float ysec2 = cubmin.y + cut * 2.f; float ysec1 = cubmin.y + cut; for (int k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; EERIE_3D curr; memcpy(&curr, &obj->vertexlist[k].v, sizeof(EERIE_3D)); long SEC; if (curr.y < ysec1) { SEC = 1; } else if (curr.y < ysec2) { SEC = 5; } else { SEC = 9; } obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); } } for (int k = 0; k < 4; k++) { if (EEfabs(obj->pbox->vert[5+k].pos.x - obj->pbox->vert[0].pos.x) < 2.f) obj->pbox->vert[5+k].pos.x = (obj->pbox->vert[1+k].pos.x + obj->pbox->vert[9+k].pos.x) * DIV2; if (EEfabs(obj->pbox->vert[5+k].pos.z - obj->pbox->vert[0].pos.z) < 2.f) obj->pbox->vert[5+k].pos.z = (obj->pbox->vert[1+k].pos.z + obj->pbox->vert[9+k].pos.z) * DIV2; } obj->pbox->radius = 0.f; for (int k = 0; k < obj->pbox->nb_physvert; k++) { float distt = TRUEEEDistance3D(&obj->pbox->vert[k].pos, &obj->pbox->vert[0].pos); if (distt > 20.f) { obj->pbox->vert[k].pos.x = (obj->pbox->vert[k].pos.x - obj->pbox->vert[0].pos.x) * 0.5f + obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = (obj->pbox->vert[k].pos.z - obj->pbox->vert[0].pos.z) * 0.5f + obj->pbox->vert[0].pos.z; } memcpy(&obj->pbox->vert[k].initpos, &obj->pbox->vert[k].pos, sizeof(EERIE_3D)); if (k != 0) { float dist = TRUEEEDistance3D(&obj->pbox->vert[0].pos, &obj->pbox->vert[k].pos); obj->pbox->radius = __max(obj->pbox->radius, dist); } } }