// // TranslateByNormal // Nixin::Point Nixin::Point::TranslateByNormal( const Point& a, const Point& b, const float length ) { float deltaX; float deltaY; float deltaZ; Point outPoint; deltaX = ( b.x - a.x ) * length / Distance3D( a, b ); deltaY = ( b.y - a.y ) * length / Distance3D( a, b ); deltaZ = ( b.z - a.z ) * length / Distance3D( a, b ); outPoint.x += deltaX; outPoint.y += deltaY; outPoint.z += deltaZ; return outPoint; }
bool Triangle3D::IsBad() { double d = Distance3D(maxBound,minBound); if(IsZero(d,0.00001))//可能的双重错误。 { return true; } return false; }
//----------------------------------------------------------------------------- // Spawns a Projectile using type, starting position/TargetPosition void ARX_MISSILES_Spawn(INTERACTIVE_OBJ *io, const long &type, const EERIE_3D *startpos, const EERIE_3D *targetpos) { long i(ARX_MISSILES_GetFree()); if (i == -1) return; missiles[i].owner = GetInterNum(io); missiles[i].type = type; missiles[i].lastpos.x = missiles[i].startpos.x = startpos->x; missiles[i].lastpos.y = missiles[i].startpos.y = startpos->y; missiles[i].lastpos.z = missiles[i].startpos.z = startpos->z; float dist; dist = 1.0F / Distance3D(startpos->x, startpos->y, startpos->z, targetpos->x, targetpos->y,targetpos->z); missiles[i].velocity.x = (targetpos->x - startpos->x) * dist; missiles[i].velocity.y = (targetpos->y - startpos->y) * dist; missiles[i].velocity.z = (targetpos->z - startpos->z) * dist; missiles[i].lastupdate = missiles[i].timecreation = ARXTimeUL(); switch (type) { case MISSILE_FIREBALL: { missiles[i].tolive = 6000; missiles[i].velocity.x *= 0.8f; missiles[i].velocity.y *= 0.8f; missiles[i].velocity.z *= 0.8f; missiles[i].longinfo = GetFreeDynLight(); if (missiles[i].longinfo != -1) { DynLight[missiles[i].longinfo].intensity = 1.3f; DynLight[missiles[i].longinfo].exist = 1; DynLight[missiles[i].longinfo].fallend = 420.f; DynLight[missiles[i].longinfo].fallstart = 250.f; DynLight[missiles[i].longinfo].rgb.r = 1.f; DynLight[missiles[i].longinfo].rgb.g = 0.8f; DynLight[missiles[i].longinfo].rgb.b = 0.6f; DynLight[missiles[i].longinfo].pos.x = startpos->x; DynLight[missiles[i].longinfo].pos.y = startpos->y; DynLight[missiles[i].longinfo].pos.z = startpos->z; } ARX_SOUND_PlaySFX(SND_SPELL_FIRE_WIND, &missiles[i].startpos, 2.0F); ARX_SOUND_PlaySFX(SND_SPELL_FIRE_LAUNCH, &missiles[i].startpos, 2.0F); } } }
void CMassParalyse::Update(unsigned long _ulTime) { ulCurrentTime += _ulTime; if (ulCurrentTime < ulDuration) { int nb = inter.nbmax, nb2; while (nb--) { if (inter.iobj[nb]) { float d = Distance3D(ePos.x, ePos.y, ePos.z, inter.iobj[nb]->pos.x, inter.iobj[nb]->pos.y, inter.iobj[nb]->pos.z); if (d <= fRayon) { nb2 = iNbParalyse; while (nb2--) { if (tabparalyse[nb2].id == nb) break; } if (nb2 < 0) { tabparalyse[iNbParalyse].id = nb; tabparalyse[iNbParalyse].paralyse = new CParalyse(); (tabparalyse[iNbParalyse].paralyse)->Create(4, 50, 200.f, 150.f, &inter.iobj[nb]->pos, 10000); iNbParalyse++; } } } } nb = iNbParalyse; while (nb--) { tabparalyse[nb].paralyse->Update(_ulTime); } } }
//----------------------------------------------------------------------------- // Updates all currently launched projectiles void ARX_MISSILES_Update() { long framediff, framediff2, framediff3; EERIE_3D orgn, dest, hit; TextureContainer * tc = TC_fire; EERIEPOLY *tp = NULL; unsigned long tim = ARXTimeUL(); for (unsigned long i(0); i < MAX_MISSILES; i++) { if (missiles[i].type == MISSILE_NONE) continue; framediff = missiles[i].timecreation + missiles[i].tolive - tim; if (framediff < 0) { ARX_MISSILES_Kill(i); continue; } framediff2 = missiles[i].timecreation + missiles[i].tolive - missiles[i].lastupdate; framediff3 = tim - missiles[i].timecreation; switch (missiles[i].type) { case MISSILE_FIREBALL : { EERIE_3D pos; pos.x = missiles[i].startpos.x + missiles[i].velocity.x * framediff3; pos.y = missiles[i].startpos.y + missiles[i].velocity.y * framediff3; pos.z = missiles[i].startpos.z + missiles[i].velocity.z * framediff3; if (missiles[i].longinfo != -1) { DynLight[missiles[i].longinfo].pos.x = pos.x; DynLight[missiles[i].longinfo].pos.y = pos.y; DynLight[missiles[i].longinfo].pos.z = pos.z; } if (USE_COLLISIONS) { orgn.x = missiles[i].lastpos.x; orgn.y = missiles[i].lastpos.y; orgn.z = missiles[i].lastpos.z; dest.x = pos.x; dest.y = pos.y; dest.z = pos.z; EERIEPOLY *ep; EERIEPOLY *epp; EERIE_3D tro; tro.x = 70.0F; tro.y = 70.0F; tro.z = 70.0F; CURRENTINTER = NULL; ep = GetMinPoly(dest.x, dest.y, dest.z); epp = GetMaxPoly(dest.x, dest.y, dest.z); if (Distance3D(player.pos.x, player.pos.y, player.pos.z, pos.x, pos.y, pos.z) < 200.0F) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&pos); Add3DBoom(&pos, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if (ep && ep->center.y < dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if (epp && epp->center.y > dest.y) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if (EERIELaunchRay3(&orgn, &dest, &hit, tp, 1)) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&hit); Add3DBoom(&hit, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } if ( !EECheckInPoly(&dest) || EEIsUnderWaterFast(&dest) ) //ARX: jycorbel (2010-08-20) - rendering issues with bGATI8500: optimize time to render; { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } long ici = IsCollidingAnyInter(dest.x, dest.y, dest.z, &tro); if (ici != -1 && ici != missiles[i].owner) { ARX_MISSILES_Kill(i); ARX_BOOMS_Add(&dest); Add3DBoom(&dest, NULL); DoSphericDamage(&dest, 180.0F, 200.0F, DAMAGE_AREAHALF, DAMAGE_TYPE_FIRE | DAMAGE_TYPE_MAGICAL); break; } } long j = ARX_PARTICLES_GetFree(); if (j != -1 && !ARXPausedTimer) { ParticleCount++; particle[j].exist = TRUE; particle[j].zdec = 0; particle[j].ov.x = pos.x; particle[j].ov.y = pos.y; particle[j].ov.z = pos.z; particle[j].move.x = missiles[i].velocity.x + 3.0f - 6.0F * rnd(); particle[j].move.y = missiles[i].velocity.y + 4.0F - 12.0F * rnd(); particle[j].move.z = missiles[i].velocity.z + 3.0F - 6.0F * rnd(); particle[j].timcreation = tim; particle[j].tolive = 500 + (unsigned long)(rnd() * 500.f); particle[j].tc = tc; particle[j].siz = 12.0F * (float)(missiles[i].tolive - framediff3) * DIV4000; particle[j].scale.x = 15.0F + rnd() * 5.0F; particle[j].scale.y = 15.0F + rnd() * 5.0F; particle[j].scale.z = 15.0F + rnd() * 5.0F; particle[j].special = FIRE_TO_SMOKE; } missiles[i].lastpos.x = pos.x; missiles[i].lastpos.y = pos.y; missiles[i].lastpos.z = pos.z; break; } } missiles[i].lastupdate = tim; } }
void B9SupportStructure::ForceUpdate() { QVector3D topFinalNormal;//result of combinging angle factor with source normal. QVector3D bottomFinalNormal; QVector3D alongMidDownNormal; QVector3D alongMidUpNormal; QVector3D topPivotCross; QVector3D bottomPivotCross; if(isGrounded) { bottomPoint.setZ(-instanceParent->GetPos().z()); } length = Distance3D(GetTopPoint(),GetBottomPoint()); //Compute real normal using angle factors topFinalNormal = topNormal; topFinalNormal.setX(topNormal.x()*topAngleFactor); topFinalNormal.setY(topNormal.y()*topAngleFactor); topFinalNormal.normalize(); bottomFinalNormal = bottomNormal; bottomFinalNormal.setX(bottomNormal.x()*bottomAngleFactor); bottomFinalNormal.setY(bottomNormal.y()*bottomAngleFactor); bottomFinalNormal.normalize(); //Compute pivot positions topPivot = topPoint - topFinalNormal*topLength; bottomPivot = bottomPoint - bottomFinalNormal*bottomLength; //Compute midExtensions based on normal angles, //these extensions are to cover up top and botton shape gaps. alongMidDownNormal = (bottomPivot - topPivot); alongMidDownNormal.normalize(); topPivotCross = QVector3D::crossProduct(topFinalNormal,alongMidDownNormal); topMidExtension = topPivotCross.length()*topRadius; topMidExtensionPoint = topPivot - alongMidDownNormal*topMidExtension; alongMidUpNormal = (topPivot - bottomPivot); alongMidUpNormal.normalize(); bottomPivotCross = QVector3D::crossProduct(bottomFinalNormal,alongMidUpNormal); if(isGrounded) { bottomMidExtension = midRadius*2*bottomPivotCross.length(); } else bottomMidExtension = bottomPivotCross.length()*bottomRadius; bottomMidExtensionPoint = bottomPivot - alongMidUpNormal*bottomMidExtension; //True rendered mid length midLength = Distance3D(topMidExtensionPoint,bottomMidExtensionPoint); //Compute PenetrationPoints (the true end points that are rendered/baked) topPenetrationPoint = topPoint + topFinalNormal*topPenetration; bottomPenetrationPoint = bottomPoint + bottomFinalNormal*bottomPenetration; //Compute Euler rotations for top, mid, and bottom shapes topThetaX = qAcos(topFinalNormal.z())*(180/M_PI); topThetaZ = qAtan2(topFinalNormal.y(),topFinalNormal.x())*(180/M_PI)-90; if(topThetaZ <= 90) topThetaZ += 180; midThetaX = qAcos((topMidExtensionPoint.z() - bottomMidExtensionPoint.z())/midLength)*(180/M_PI); midThetaZ = qAtan2((topMidExtensionPoint.y() - bottomMidExtensionPoint.y()), (topMidExtensionPoint.x() - bottomMidExtensionPoint.x()))*(180/M_PI)-90; if(midThetaZ <= 90) midThetaZ += 180; bottomThetaX = qAcos(bottomFinalNormal.z())*(180/M_PI)+180; bottomThetaZ = qAtan2(bottomFinalNormal.y(),bottomFinalNormal.x())*(180/M_PI)-90; if(bottomThetaZ <= 90) bottomThetaZ += 180; }
//----------------------------------------------------------------------------- void CIncinerate::Create(EERIE_3D _eSrc, float _fBeta) { SetDuration(ulDuration); SetAngle(_fBeta); eSrc.x = _eSrc.x; eSrc.y = _eSrc.y - 20; eSrc.z = _eSrc.z; eTarget.x = eSrc.x - fBetaRadSin * 500; eTarget.y = eSrc.y; eTarget.z = eSrc.z + fBetaRadCos * 500; fSize = 1; int i = 0; iMax = iNumber; EERIE_3D s, e, h; s.x = eSrc.x; s.y = eSrc.y - 20; s.z = eSrc.z; e.x = eSrc.x; e.y = eSrc.y - 20; e.z = eSrc.z; e.x = s.x - fBetaRadSin * 900; e.y = s.y; e.z = s.z + fBetaRadCos * 900; float fd; i = iMax; if (!Visible(&s, &e, NULL, &h)) { e.x = h.x + fBetaRadSin * 20; e.y = h.y; e.z = h.z - fBetaRadCos * 20; } fd = Distance3D(s.x, s.y, s.z, e.x, e.y, e.z); float fDur = ulDuration * (fd / 900.0f); ARX_CHECK_ULONG(fDur); SetDuration(ARX_CLEAN_WARN_CAST_ULONG(fDur)); float fCalc = (fd / 900.0f) * iMax ; ARX_CHECK_INT(fCalc); i = ARX_CLEAN_WARN_CAST_INT(fCalc); iNumber = i; int end = 40; tv1a[0].sx = s.x; tv1a[0].sy = s.y; tv1a[0].sz = s.z; tv1a[end].sx = e.x; tv1a[end].sy = e.y; tv1a[end].sz = e.z; Split(tv1a, 0, end, 10, 1, 0, 1, 10, 1); CParticleParams cp; cp.iNbMax = 250; cp.fLife = 1000; cp.fLifeRandom = 500; cp.p3Pos.x = 0; cp.p3Pos.y = 10; cp.p3Pos.z = 0; cp.p3Direction.x = + fBetaRadSin * 4; cp.p3Direction.y = 0; cp.p3Direction.z = - fBetaRadCos * 4; cp.fAngle = DEG2RAD(1); cp.fSpeed = 0; cp.fSpeedRandom = 20; cp.p3Gravity.x = 0; cp.p3Gravity.y = 0; cp.p3Gravity.z = 0; cp.fFlash = 0; cp.fRotation = 0; cp.bRotationRandomDirection = false; cp.bRotationRandomStart = false; cp.fStartSize = 5; cp.fStartSizeRandom = 5; cp.fStartColor[0] = 80; cp.fStartColor[1] = 80; cp.fStartColor[2] = 0; cp.fStartColor[3] = 20; cp.fStartColorRandom[0] = 81; cp.fStartColorRandom[1] = 81; cp.fStartColorRandom[2] = 51; cp.fStartColorRandom[3] = 51; cp.bStartLock = true; cp.fEndSize = 1; cp.fEndSizeRandom = 5; cp.fEndColor[0] = 50; cp.fEndColor[1] = 0; cp.fEndColor[2] = 0; cp.fEndColor[3] = 20; cp.fEndColorRandom[0] = 50; cp.fEndColorRandom[1] = 50; cp.fEndColorRandom[2] = 50; cp.fEndColorRandom[3] = 20; cp.bEndLock = true; cp.bTexLoop = true; cp.iBlendMode = 3; pPSStream.SetParams(cp); pPSStream.ulParticleSpawn = 0; pPSStream.SetTexture("graph\\particles\\smallfire", 4, 10); pPSStream.fParticleFreq = 250; pPSStream.bParticleFollow = false; pPSStream.SetPos(eSrc); pPSStream.Update(0); // Hit cp.iNbMax = 150; cp.fLife = 2000; cp.fLifeRandom = 1000; cp.p3Pos.x = 80; cp.p3Pos.y = 10; cp.p3Pos.z = 80; cp.p3Direction.x = 0; cp.p3Direction.y = 2; cp.p3Direction.z = 0; cp.fAngle = 0; cp.fSpeed = 0; cp.fSpeedRandom = 0; cp.p3Gravity.x = 0; cp.p3Gravity.y = 0; cp.p3Gravity.z = 0; cp.fFlash = 0; cp.fRotation = 0; cp.bRotationRandomDirection = false; cp.bRotationRandomStart = false; cp.fStartSize = 10; cp.fStartSizeRandom = 3; cp.fStartColor[0] = 25; cp.fStartColor[1] = 25; cp.fStartColor[2] = 25; cp.fStartColor[3] = 50; cp.fStartColorRandom[0] = 51; cp.fStartColorRandom[1] = 51; cp.fStartColorRandom[2] = 51; cp.fStartColorRandom[3] = 101; cp.bStartLock = false; cp.fEndSize = 10; cp.fEndSizeRandom = 3; cp.fEndColor[0] = 25; cp.fEndColor[1] = 25; cp.fEndColor[2] = 25; cp.fEndColor[3] = 50; //0 cp.fEndColorRandom[0] = 0; cp.fEndColorRandom[1] = 0; cp.fEndColorRandom[2] = 0; cp.fEndColorRandom[3] = 100; //0 cp.bEndLock = false; cp.bTexLoop = true; cp.iBlendMode = 0; pPSHit.SetParams(cp); pPSHit.ulParticleSpawn = 0; pPSHit.SetTexture("graph\\particles\\firebase", 4, 100); pPSHit.fParticleFreq = -1; pPSHit.SetPos(eSrc); pPSHit.Update(0); }
void CreateParametricSurface(POINT_MATRIX *Q,int p,int q,BSPLINE_SURFACE *b) { int k,l; int m,n,num; double *uk,*ul,*cds,d,total; m=Q->m; n=Q->n; b->p=p; b->q=q; b->net=CreateControlNet(m,n); b->knu=CreateKnotVector(Q->m+p+1); b->knv=CreateKnotVector(Q->n+q+1); uk=(double *)calloc(m,sizeof(double)); ul=(double *)calloc(n,sizeof(double)); cds=(double *)calloc(m>n?m+1:n+1,sizeof(double)); num=m+1; total=0.0; uk[0]=0.0; uk[n]=1.0; for(k=1;k<n;k++) uk[k]=0.0; for(l=0;l<n;l++) { total=0.0; for(k=1;k<m;k++) { cds[k]=Distance3D(Q->element[k][l],Q->element[k-1][l]); total+=cds[k]; } } if(total==0.0) num--; else { d=0.0; for(k=1;k<n;k++) { d+=cds[k]; uk[k]+=d/total; } } for(k=1;k<n;k++) uk[k]/=num; num=n+1; total=0.0; ul[0]=0.0; ul[m]=1.0; for(k=1;k<m;k++) ul[k]=0.0; for(l=0;l<=n;l++) { total=0.0; for(k=1;k<m;k++) { cds[k]=Distance3D(Q->element[k][l],Q->element[k-1][l]); total+=cds[k]; } } if(total==0.0) num--; else { d=0.0; for(k=1;k<m;k++) { d+=cds[k]; ul[k]+=d/total; } } for(k=1;k<m;k++) ul[k]/=num; for(k=0;k<n;k++) printf("uk[%d]:%g\n",k,uk[k]); for(k=0;k<m;k++) printf("ul[%d]:%g\n",k,ul[k]); }