int UpdatePlayer(GameInput *Input, GameState *State) { Entity *Player = &State->Entities[State->PlayerEntity]; vec2 Acceleration = {0, 0}; if(Input->IndividualButtons.W.Pressed) Acceleration.y -= 1.0f; if(Input->IndividualButtons.S.Pressed) Acceleration.y += 1.0f; if(Input->IndividualButtons.A.Pressed) Acceleration.x -= 1.0f; if(Input->IndividualButtons.D.Pressed) Acceleration.x += 1.0f; if(Acceleration.x || Acceleration.y) Acceleration = NormalizeVector(Acceleration); Acceleration = Acceleration * Player->Speed; Player->Vel = Player->Vel + (Acceleration - Player->Vel * 4) * Input->TimeDelta; Player->Pos = Player->Pos + (Player->Vel * Input->TimeDelta) + (Acceleration * Input->TimeDelta * Input->TimeDelta * 0.5); Player->Direction = NormalizeVector(Input->MousePos - Player->Pos); return 0; }
bool ICollisionSystem::Intersection(sf::Shape& theMovingShape, sf::Shape& theOtherShape, sf::Vector2f& theMinimumTranslation) { //Exit if either shape is empty; if(theMovingShape.getPointCount()==0 || theOtherShape.getPointCount()==0) return false; //Variables std::vector<sf::Vector2f> anAxes; Uint32 anIndex; sf::Vector2f anSmallestAxis; double anOverlap=std::numeric_limits<double>::max(); Uint32 anMovingPointCount=theMovingShape.getPointCount(); Uint32 anOtherPointCount=theOtherShape.getPointCount(); sf::Vector2f anPointA, anPointB; //Axes for this object. for(anIndex=0;anIndex<anMovingPointCount-1;++anIndex) { anPointA=theMovingShape.getPoint(anIndex); anPointB=theMovingShape.getPoint(anIndex+1); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); } anPointA=theMovingShape.getPoint(anMovingPointCount-1); anPointB=theMovingShape.getPoint(0); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); //Axes for other object. for(anIndex=0;anIndex<theOtherShape.getPointCount()-1;++anIndex) { anPointA=theOtherShape.getPoint(anIndex); anPointB=theOtherShape.getPoint(anIndex+1); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); } anPointA=theOtherShape.getPoint(anOtherPointCount-1); anPointB=theOtherShape.getPoint(0); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); for(anIndex=0;anIndex<anAxes.size();++anIndex) { float anMinA, anMaxA, anMinB, anMaxB; // ... project the points of both OBBs onto the axis ... ProjectOntoAxis(theMovingShape,anAxes[anIndex], anMinA, anMaxA); ProjectOntoAxis(theOtherShape,anAxes[anIndex], anMinB, anMaxB); // ... and check whether the outermost projected points of both OBBs overlap. // If this is not the case, the Seperating Axis Theorem states that there can be no collision between the rectangles if(!((anMinB<=anMaxA)&&(anMaxB>=anMinA))) { return false; } double o; if(anMinB<=anMaxA) o=anMaxA-anMinB; else o=anMaxB-anMinA; if(o<anOverlap) { anSmallestAxis=anAxes[anIndex]; anOverlap=o; } } theMinimumTranslation=anSmallestAxis; theMinimumTranslation*=(float)anOverlap; return true; }
static void glhLookAtf2( float *matrix, float *eyePosition3D, float *center3D, float *upVector3D ) { #define ComputeNormalOfPlane ComputeNormalOfPlaneFLOAT_2 #define NormalizeVector NormalizeVectorFLOAT_2 #ifdef BUILD_USE_GLHLIB float resultMatrix[16]; #endif float forward[3], side[3], up[3]; float matrix2[16]; //------------------ forward[0] = center3D[0] - eyePosition3D[0]; forward[1] = center3D[1] - eyePosition3D[1]; forward[2] = center3D[2] - eyePosition3D[2]; NormalizeVector(forward); //------------------ //Side = forward x up ComputeNormalOfPlane(side, forward, upVector3D); NormalizeVector(side); //------------------ //Recompute up as: up = side x forward ComputeNormalOfPlane(up, side, forward); //------------------ matrix2[0] = side[0]; matrix2[4] = side[1]; matrix2[8] = side[2]; matrix2[12] = 0.0; //------------------ matrix2[1] = up[0]; matrix2[5] = up[1]; matrix2[9] = up[2]; matrix2[13] = 0.0; //------------------ matrix2[2] = -forward[0]; matrix2[6] = -forward[1]; matrix2[10] = -forward[2]; matrix2[14] = 0.0; //------------------ matrix2[3] = matrix2[7] = matrix2[11] = 0.0; matrix2[15] = 1.0; //------------------ #ifdef BUILD_USE_GLHLIB MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2); glhTranslatef2(resultMatrix, -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); //------------------ memcpy(matrix, resultMatrix, 16*sizeof(float)); #else glMultMatrixf(matrix2); glTranslatef( -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2] ); #endif }
void BuildXiwMatrix(GzCamera *camera) { IdentityMatrix(camera->Xiw); GzCoord right; GzCoord look; // build look-vector look[0] = camera->lookat[0] - camera->position[0]; look[1] = camera->lookat[1] - camera->position[1]; look[2] = camera->lookat[2] - camera->position[2]; NormalizeVector(look, look); // build up-vector float upDotZ = DotProduct(camera->worldup, look); camera->worldup[0] = camera->worldup[0] - upDotZ * look[0]; camera->worldup[1] = camera->worldup[1] - upDotZ * look[1]; camera->worldup[2] = camera->worldup[2] - upDotZ * look[2]; NormalizeVector(camera->worldup, camera->worldup); // build right-vector CrossProduct(camera->worldup, look, right); NormalizeVector(right, right); // build matrix camera->Xiw[0][0] = right[0]; camera->Xiw[0][1] = right[1]; camera->Xiw[0][2] = right[2]; camera->Xiw[1][0] = camera->worldup[0]; camera->Xiw[1][1] = camera->worldup[1]; camera->Xiw[1][2] = camera->worldup[2]; camera->Xiw[2][0] = look[0]; camera->Xiw[2][1] = look[1]; camera->Xiw[2][2] = look[2]; // build upper right column GzCoord tRight = {-right[0], -right[1], -right[2]}; GzCoord tUp = {-camera->worldup[0], -camera->worldup[1], -camera->worldup[2]}; GzCoord tLook = {-look[0], -look[1], -look[2]}; //up - (up . Z)Z camera->Xiw[0][3] = DotProduct(tRight, camera->position); camera->Xiw[1][3] = DotProduct(tUp, camera->position); camera->Xiw[2][3] = DotProduct(tLook, camera->position); /*fprintf(outf, "Camera vectors\n"); fprintf(outf, " right: "); PrintGzCoord(right); fprintf(outf, " up: "); PrintGzCoord(camera->worldup); fprintf(outf, " look: "); PrintGzCoord(look); fprintf(outf, " pos: "); PrintGzCoord(camera->position);*/ }
LTriangle2 LMesh::GetTriangle2(uint index) { LTriangle2 f; LTriangle t = GetTriangle(index); f.vertices[0] = GetVertex(t.a); f.vertices[1] = GetVertex(t.b); f.vertices[2] = GetVertex(t.c); f.vertexNormals[0] = GetNormal(t.a); f.vertexNormals[1] = GetNormal(t.b); f.vertexNormals[2] = GetNormal(t.c); f.textureCoords[0] = GetUV(t.a); f.textureCoords[1] = GetUV(t.b); f.textureCoords[2] = GetUV(t.c); LVector3 a, b; a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0])); b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2])); f.faceNormal = CrossProduct(b, a); f.faceNormal = NormalizeVector(f.faceNormal); f.materialId = m_tris[index].materialId; return f; }
const PolyphaseFilter *MakePolyphaseFilter( int iUpFactor, float fCutoffFrequency ) { PolyphaseFiltersLock.Lock(); pair<int,float> params( make_pair(iUpFactor, fCutoffFrequency) ); FilterMap::const_iterator it = g_mapPolyphaseFilters.find(params); if( it != g_mapPolyphaseFilters.end() ) { /* We already have a filter for this upsampling factor and cutoff; use it. */ PolyphaseFilter *pPolyphase = it->second; PolyphaseFiltersLock.Unlock(); return pPolyphase; } int iWinSize = L*iUpFactor; float *pFIR = new float[iWinSize]; GenerateSincLowPassFilter( pFIR, iWinSize, fCutoffFrequency ); ApplyKaiserWindow( pFIR, iWinSize, 8 ); NormalizeVector( pFIR, iWinSize ); MultiplyVector( &pFIR[0], &pFIR[iWinSize], (float) iUpFactor ); PolyphaseFilter *pPolyphase = new PolyphaseFilter( iUpFactor ); pPolyphase->Generate( pFIR ); delete [] pFIR; g_mapPolyphaseFilters[params] = pPolyphase; PolyphaseFiltersLock.Unlock(); return pPolyphase; }
void TScene::RenderPlanet(float radius, Vector pos, int NumMesh) { glLoadIdentity(); float dist = DistanceBetweenVector(pos, Camera->GetPosition()); //glPrint(10, 60, "dist: %f", dist); if (dist < 1000.0f) { glTranslatef(pos.x, pos.y, pos.z); glScalef(radius, radius, radius); //glPrint(10, 90, "PosPlanet: %f, %f, %f", pos.x, pos.y, pos.z); } else { Vector cam = Camera->GetPosition(); Vector a = NormalizeVector( cam - pos); pos = cam - ScaleVector ( a, 1000.0f ); glTranslatef( pos.x, pos.y, pos.z ); float scale = (radius / dist) * 1000.0f; glScalef(scale, scale, scale); //glPrint(10, 90, "PosPlanet: %f, %f, %f", pos.x, pos.y, pos.z); //glPrint(10, 120, "scale: %f", scale); } Mesh[NumMesh].Render(); }
void TScene::RenderShipPreview(Vector pos,Vector dir, Vector up, int NumMesh) { // glPushMatrix(); // glLoadIdentity(); float mmodel[16]={0}; Vector a(0,0,0),b(0,0,0); Vector eye=Camera->GetPosition()-pos; eye=NormalizeVector(eye); a=CrossProduct(&eye,&Camera->UpVector); a=NormalizeVector(a); b=CrossProduct(&a,&eye);//*-1.0f; // D3DXMatrixLookAtLH (&matView, &(eye*150.0f),&(b*50.0f), &World.aiGlobal.cam->GetTy()); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(eye.x*40.0f,eye.y*40.0f,eye.z*40.0f,-b.x*10.0f,-b.y*10.0f,-b.z*10.0f,Camera->UpVector.x,Camera->UpVector.y,Camera->UpVector.z); // engine->m_d3dDevice->SetTransform (D3DTS_VIEW, &matView); glGetFloatv(GL_MODELVIEW_MATRIX, mmodel); // World.resManager.m_Res[World.aiGlobal.cam->target->gRes].p_d3dx_mesh->DrawSubset( 0 ); // if (World.aiGlobal.cam->target){ // matWorld=World.aiGlobal.cam->target->GetCurMatrix(); // engine->m_d3dDevice->SetTransform(D3DTS_WORLD, &matWorld); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMultMatrixf(ProjectionMatrix); // glMultTransposeMatrixf(mmodel); glMultMatrixf(mmodel); // glPushMatrix(); // glPopMatrix(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,0,dir.x,dir.y,dir.z,up.x,up.y,up.z); glGetFloatv(GL_MODELVIEW_MATRIX, mmodel); // glPopMatrix(); glLoadIdentity(); // glTranslatef(pos.x, pos.y, pos.z); glMultTransposeMatrixf(mmodel); Mesh[NumMesh].Render(); // glPopMatrix(); }
//---------------------------------------------------------------------- void LookAt(double *eye, double *target, double *upV, double *modelMatrix) { double forward[3], side[3], up[3]; double matrix2[16], resultMatrix[16]; //------------------ forward[0] = target[0] - eye[0]; forward[1] = target[1] - eye[1]; forward[2] = target[2] - eye[2]; NormalizeVector(forward); //------------------ //Side = forward x up ComputeNormalOfPlane(side, forward, upV); NormalizeVector(side); //------------------ //Recompute up as: up = side x forward ComputeNormalOfPlane(up, side, forward); //------------------ matrix2[0] = side[0]; matrix2[4] = side[1]; matrix2[8] = side[2]; matrix2[12] = 0.0; //------------------ matrix2[1] = up[0]; matrix2[5] = up[1]; matrix2[9] = up[2]; matrix2[13] = 0.0; //------------------ matrix2[2] = -forward[0]; matrix2[6] = -forward[1]; matrix2[10] = -forward[2]; matrix2[14] = 0.0; //------------------ matrix2[3] = matrix2[7] = matrix2[11] = 0.0; matrix2[15] = 1.0; //------------------ MultiplyMatrices(resultMatrix, modelMatrix, matrix2); Translate(resultMatrix, -eye[0], -eye[1], -eye[2]); //------------------ memcpy(modelMatrix, resultMatrix, 16*sizeof(double)); }
//TODO MDInitialize vorticities int InitializeTurbModes ( const MDConstants K, const Molecule* molecule, const TurbConstVecs* turb_vecs, const TurbConsts* turb, KraichnanMode** kraich_modes, const unsigned t ) { //TODO profile & parallelise //TODO check valid input/output /* #pragma omp parallel for default (none) \ shared (K.PartNum, molecule, turb_vecs, turb, K.Lx, K.Ly, K.Lz, t, delta_t, NF)\ schedule(dynamic, 5000) */ for(unsigned i = 0; i < K.PartNum; ++i) { for(unsigned modeIndex = 0; modeIndex < K.NF; ++modeIndex) { double pos_vec[kDIM] = {0}; NormalizeVector (K.L, molecule[i].position, pos_vec); double kn_dot_x = DotProd ( turb_vecs[modeIndex].kn, pos_vec); unsigned real_time = t * K.delta_t; //in LaTeX would be: \Omega_n = |\kappa| (\vec k \cdot \vec x) + |\omega| t double Omega_n = turb[modeIndex].k * kn_dot_x + turb[modeIndex].omega * real_time; //cos and sin kraich_modes[i][modeIndex].sin = sin (Omega_n); kraich_modes[i][modeIndex].cos = cos (Omega_n); assert (kraich_modes[i][modeIndex].sin < 1); assert (kraich_modes[i][modeIndex].sin > -1); assert (kraich_modes[i][modeIndex].cos < 1); assert (kraich_modes[i][modeIndex].cos > -1); } } return 0; }
void Extrusion::Draw( void ) { double l2 = length / 2.0; int i, j; Vector3 delta, normal; if ( ! enabled ) return; PrepDraw(); /* Draw the ends first. */ glBegin( GL_POLYGON ); glNormal3d( 0.0, 0.0, - 1.0 ); for ( i = 0; i < vertices; i++ ) glVertex3d( vertex[i][X], vertex[i][Y], l2 ); glEnd(); glBegin( GL_POLYGON ); glNormal3d( 0.0, 0.0, 1.0 ); for ( i = vertices - 1; i >= 0; i-- ) glVertex3d( vertex[i][X], vertex[i][Y], - l2 ); glEnd(); /* Now draw the facets. */ for ( i = 0; i < vertices; i++ ) { j = ( i + 1 ) % vertices; // subtract_vectors( vertex[i], vertex[j], delta ); delta[0] = vertex[i][0] - vertex[j][0]; delta[1] = vertex[i][1] - vertex[j][1]; delta[2] = 0.0; ComputeCrossProduct( normal, delta, kVector ); NormalizeVector( normal ); glBegin( GL_POLYGON ); glNormal3dv( normal ); glVertex3d( vertex[i][X], vertex[i][Y], - l2 ); glVertex3d( vertex[i][X], vertex[i][Y], l2 ); glVertex3d( vertex[j][X], vertex[j][Y], l2 ); glVertex3d( vertex[j][X], vertex[j][Y], - l2 ); glEnd(); } FinishDraw(); }
double MeanKineticEnergy ( const MDConstants K, const Molecule **positions, const TurbField **turb_velocities ) { double time_mean = 0; for (unsigned n = 0; n < K.SnapshotNum; ++n) // calc mean over time { double part_mean = 0; //for every new timestep for (unsigned i = 0; i < K.PartNum; ++i)//calc mean over particles { double v_part[kDIM] = {0}; double v_0[kDIM]; InitConstArray (v_0, kDIM, K.v_0);// v_0 * \vec{e_part} NormalizeVector (v_0, positions[n][i].direction, v_part); double v[kDIM]; //temp array SumVector (v_part, turb_velocities[n][i].direction, v); double kin_energy = KineticEnergy (v); part_mean += kin_energy; assert (part_mean >= 0); } part_mean /= K.PartNum; time_mean += part_mean; assert (time_mean > 0); } time_mean /= (K.iteration_num * K.delta_t); return time_mean; }
void HUD_CreateBenchObjects( vec3_t origin ) { static cl_entity_t bench[ NUM_BENCH_OBJ ]; cl_entity_t *player; vec3_t forward, right, up; vec3_t farpoint; vec3_t centerspot; static int first = true; static int failed = false; static float last_time; float frametime; float frac; float frac2; float dt; pmtrace_t tr; int i = 0; if ( gHUD.m_flTime == last_time ) return; frametime = gHUD.m_flTime - last_time; last_time = gHUD.m_flTime; if ( frametime <= 0.0 ) return; if ( failed ) return; player = gEngfuncs.GetLocalPlayer(); if ( !player ) { failed = true; return; } if ( first ) { first = false; if ( !HUD_SetupBenchObjects( bench, player->index - 1, origin ) ) { failed = true; return; } } gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers ( player->index - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); dt = gHUD.m_flTime - g_flStartTime; if ( dt < 0 ) return; frac = dt / BENCH_CYCLE_TIME; if ( frac > 1.0 ) { frac = frac - (float)(int)frac; } frac2 = dt /BENCH_INNER_CYCLE_TIME; if ( frac2 > 1.0 ) { frac2 = frac2 - (float)(int)frac2; } // Determine forward vector AngleVectors ( vec3_origin, forward, right, up ); centerspot = origin; centerspot[2] -= 512; gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)&origin, (float *)¢erspot, PM_NORMAL, -1, &tr ); centerspot = tr.endpos; centerspot[2] += BENCH_BALLHEIGHT; // Move center out from here centerspot = centerspot + BENCH_VIEW_OFFSET * forward; for ( i = 0; i < NUM_BENCH_OBJ; i++ ) { int j; float jitter = 0.0; float jfrac; float offset; float ofs_radius = 5.0; vec3_t ang; offset = ( float ) i / (float) ( NUM_BENCH_OBJ - 1 ); ang[ 0 ] = 0; ang[ 2 ] = 0; ang[ 1 ] = BENCH_SWEEP * offset + frac * 360.0; // normalize NormalizeVector( ang ); // Determine forward vector AngleVectors ( ang, forward, right, up ); // Get a far point for ray trace farpoint = centerspot + ( BENCH_RADIUS + ofs_radius * sin( BENCH_SWEEP * offset + frac2 * 2 * M_PI ) ) * forward; farpoint[2] += 10 * cos( BENCH_SWEEP * offset + frac2 * 2 * M_PI ); gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)¢erspot, (float *)&farpoint, PM_NORMAL, -1, &tr ); // Add angular velocity VectorMA( bench[ i ].curstate.angles, frametime, bench[ i ].baseline.angles, bench[ i ].curstate.angles ); NormalizeVector( bench[ i ].curstate.angles ); jfrac = ( (float)gHUD.m_Benchmark.GetObjects() / (float)NUM_BENCH_OBJ ); // Adjust velocity //bench[ i ].curstate.velocity[ 2 ] -= bench[ i ].curstate.gravity * frametime * 800; /* // Did we hit something? if ( tr.fraction != 1.0 && !tr.inwater ) { float damp; float proj; vec3_t traceNormal; int j; traceNormal = tr.plane.normal; damp = 0.9; // Reflect velocity if ( damp != 0 ) { proj = DotProduct( bench[ i ].curstate.velocity, traceNormal ); VectorMA( bench[ i ].curstate.velocity, -proj*2, traceNormal, bench[ i ].curstate.velocity ); // Reflect rotation (fake) for ( j = 0 ; j < 3; j++ ) { if ( bench[ i ].curstate.velocity[ j ] > 1000.0 ) { bench[ i ].curstate.velocity[ j ] = 1000.0; } else if ( bench[ i ].curstate.velocity[ j ] < -1000.0 ) { bench[ i ].curstate.velocity[ j ] = -1000.0; } } bench[ i ].baseline.angles[1] = -bench[ i ].baseline.angles[1]; VectorScale( bench[ i ].curstate.velocity, damp, bench[ i ].curstate.velocity ); } } */ if ( i == ( NUM_BENCH_OBJ - 1 ) ) { g_aimorg = tr.endpos; } if ( Bench_GetPowerPlay() ) { jitter = 0.5; } else { jitter = 8.0; } jitter *= jfrac; for ( j = 0; j < 2; j++ ) { tr.endpos[ j ] += gEngfuncs.pfnRandomFloat( -jitter, jitter ); } // Add to visedicts list for rendering // Move dot to trace endpoint bench[ i ].origin = tr.endpos; bench[ i ].curstate.origin = bench[ i ].origin; bench[ i ].angles = bench[ i ].curstate.angles; // Force no interpolation, etc., probably not necessary bench[ i ].prevstate = bench[ i ].curstate; if ( ( NUM_BENCH_OBJ - i - 1 ) < gHUD.m_Benchmark.GetObjects() ) { if ( bench[ i ].curstate.renderamt == 255 ) { bench[i].curstate.rendermode = kRenderNormal; } else { bench[i].curstate.renderamt += BLEND_IN_SPEED * frametime; bench[i].curstate.renderamt = min( 255, bench[i].curstate.renderamt ); bench[i].curstate.rendermode = kRenderTransAlpha; } gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &bench[ i ] ); } } gEngfuncs.pEventAPI->EV_PopPMStates(); }
int HUD_SetupBenchObjects( cl_entity_t *bench, int plindex, vec3_t origin ) { int i, j; vec3_t ang; float offset; struct model_s *mdl; int index; vec3_t forward, right, up; vec3_t farpoint; vec3_t centerspot; pmtrace_t tr; ang = vec3_origin; //ang[1] = 90.0; // Determine forward vector AngleVectors ( ang, forward, right, up ); // Try to find the laserdot sprite model and retrieve the modelindex for it mdl = gEngfuncs.CL_LoadModel( "models/spikeball.mdl", &index ); if ( !mdl ) return 0; gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers ( plindex ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); centerspot = origin; centerspot[2] -= 512; gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)&origin, (float *)¢erspot, PM_NORMAL, -1, &tr ); centerspot = tr.endpos; centerspot[2] += BENCH_BALLHEIGHT; // Move center out from here centerspot = centerspot + BENCH_VIEW_OFFSET * forward; g_flStartTime = gHUD.m_flTime; for ( i = 0; i < NUM_BENCH_OBJ; i++ ) { offset = ( float ) i / (float) ( NUM_BENCH_OBJ - 1 ); ang[ 0 ] = 0; ang[ 2 ] = 0; ang[ 1 ] = BENCH_SWEEP * offset; // normalize NormalizeVector( ang ); // Determine forward vector AngleVectors ( ang, forward, right, up ); bench[ i ].model = mdl; bench[ i ].curstate.modelindex = index; // Set up dot info. bench[ i ].curstate.movetype = MOVETYPE_NONE; bench[ i ].curstate.solid = SOLID_NOT; // Get a far point for ray trace farpoint = centerspot + BENCH_RADIUS * forward; gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)¢erspot, (float *)&farpoint, PM_NORMAL, -1, &tr ); // Move dot to trace endpoint bench[ i ].origin = tr.endpos; bench[ i ].curstate.origin = bench[ i ].origin; //bench[ i ].curstate.gravity = 0.5; for ( j = 0; j < 2; j++ ) { // bench[ i ].curstate.velocity[ j ] = gEngfuncs.pfnRandomLong( -300, 300 ); } //bench[ i ].curstate.velocity[ 2 ] = gEngfuncs.pfnRandomLong( 0, 50 ); bench[ i ].curstate.velocity = vec3_origin; bench[ i ].curstate.angles[ 2 ] = 0.0; bench[ i ].curstate.angles[ 0 ] = 0.0; bench[ i ].curstate.angles[ 1 ] = 0.0; // gEngfuncs.pfnRandomLong( -180, 180 ); for ( j = 0; j < 3; j++ ) { // angular velocity bench[ i ].baseline.angles[ 0 ] = gEngfuncs.pfnRandomLong( -300, 300 ); //bench[ i ].baseline.angles[ 0 ] = 0; bench[ i ].baseline.angles[ 2 ] = 0; bench[ i ].baseline.angles[ 1 ] = gEngfuncs.pfnRandomLong( -300, 300 ); } bench[ i ].curstate.renderamt = 0; // Force no interpolation, etc., probably not necessary bench[ i ].prevstate = bench[ i ].curstate; } gEngfuncs.pEventAPI->EV_PopPMStates(); return 1; }
void LMesh::CalcTextureSpace() { // a understandable description of how to do that can be found here: // http://members.rogers.com/deseric/tangentspace.htm // first calculate the tangent for each triangle LVector3 x_vec, y_vec, z_vec; LVector3 v1, v2; for (uint i=0; i<m_triangles.size(); i++) { v1.x = m_vertices[m_tris[i].b].x - m_vertices[m_tris[i].a].x; v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x; v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y; v2.x = m_vertices[m_tris[i].c].x - m_vertices[m_tris[i].a].x; v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x; v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y; x_vec = CrossProduct(v1, v2); v1.x = m_vertices[m_tris[i].b].y - m_vertices[m_tris[i].a].y; v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x; v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y; v2.x = m_vertices[m_tris[i].c].y - m_vertices[m_tris[i].a].y; v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x; v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y; y_vec = CrossProduct(v1, v2); v1.x = m_vertices[m_tris[i].b].z - m_vertices[m_tris[i].a].z; v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x; v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y; v2.x = m_vertices[m_tris[i].c].z - m_vertices[m_tris[i].a].z; v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x; v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y; z_vec = CrossProduct(v1, v2); m_tris[i].tangent.x = -(x_vec.y/x_vec.x); m_tris[i].tangent.y = -(y_vec.y/y_vec.x); m_tris[i].tangent.z = -(z_vec.y/z_vec.x); m_tris[i].binormal.x = -(x_vec.z/x_vec.x); m_tris[i].binormal.y = -(y_vec.z/y_vec.x); m_tris[i].binormal.z = -(z_vec.z/z_vec.x); } // now for each vertex build a list of face that share this vertex std::vector< std::vector<int> > array; array.resize(m_vertices.size()); for (size_t i=0; i<m_triangles.size(); i++) { uint k = m_tris[i].a; array[k].push_back(int(i)); k = m_tris[i].b; array[k].push_back(int(i)); k = m_tris[i].c; array[k].push_back(int(i)); } // now average the tangents and compute the binormals as (tangent X normal) for (size_t i=0; i<m_vertices.size(); i++) { v1 = zero3; v2 = zero3; int t = int(array[i].size()); for (int k=0; k<t; k++) { v1.x += m_tris[array[i][k]].tangent.x; v1.y += m_tris[array[i][k]].tangent.y; v1.z += m_tris[array[i][k]].tangent.z; v2.x += m_tris[array[i][k]].binormal.x; v2.y += m_tris[array[i][k]].binormal.y; v2.z += m_tris[array[i][k]].binormal.z; } m_tangents[i] = NormalizeVector(v1); //m_binormals[i] = NormalizeVector(v2); m_binormals[i] = NormalizeVector(CrossProduct(m_tangents[i], m_normals[i])); } }
bool DexMouseTracker::GetCurrentMarkerFrame( CodaFrame &frame ) { POINT mouse_position; GetCursorPos( &mouse_position ); RECT rect; GetWindowRect( GetDesktopWindow(), &rect ); Vector3 position, rotated; Vector3 x_dir, y_span, z_span; Vector3 x_displacement, y_displacement, z_displacement; double x, y, z; Quaternion Ry, Rz, Q, nominalQ, midQ; Matrix3x3 xform = {{-1.0, 0.0, 0.0},{0.0, 0.0, 1.0},{0.0, 1.0, 0.0}}; int mrk, id; // Just set the target frame markers at their nominal fixed positions. for ( mrk = 0; mrk < nFrameMarkers; mrk++ ) { id = FrameMarkerID[mrk]; CopyVector( frame.marker[id].position, TargetFrameBody[mrk] ); } // Shift the vertical bar markers to simulate being in the left position. if ( IsDlgButtonChecked( dlg, IDC_LEFT ) ) { frame.marker[DEX_NEGATIVE_BAR_MARKER].position[X] += 300.0; frame.marker[DEX_POSITIVE_BAR_MARKER].position[X] += 300.0; } // Transform the marker positions of the target box and frame according // to whether the system was upright or supine when it was aligned and // according to whether the system is currently installed in the upright // or supine configuration. if ( ( IsDlgButtonChecked( dlg, IDC_SUPINE ) && TRACKER_ALIGNED_SUPINE != SendDlgItemMessage( dlg, IDC_ALIGNMENT, CB_GETCURSEL, 0, 0 ) ) || ( IsDlgButtonChecked( dlg, IDC_SEATED ) && TRACKER_ALIGNED_UPRIGHT != SendDlgItemMessage( dlg, IDC_ALIGNMENT, CB_GETCURSEL, 0, 0 ) ) ) { for ( mrk = 0; mrk < nFrameMarkers; mrk++ ) { id = FrameMarkerID[mrk]; position[X] = - frame.marker[id].position[X]; position[Z] = frame.marker[id].position[Y]; position[Y] = frame.marker[id].position[Z]; CopyVector( frame.marker[id].position, position ); } MatrixToQuaternion( nominalQ, xform ); } else CopyQuaternion( nominalQ, nullQuaternion ); // Now set the visibility flag as a funciton of the GUI. if ( IsDlgButtonChecked( dlg, IDC_BAR_OCCLUDED ) ) { frame.marker[DEX_NEGATIVE_BAR_MARKER].visibility = false; frame.marker[DEX_POSITIVE_BAR_MARKER].visibility = false; } else { frame.marker[DEX_NEGATIVE_BAR_MARKER].visibility = true; frame.marker[DEX_POSITIVE_BAR_MARKER].visibility = true; } if ( IsDlgButtonChecked( dlg, IDC_BOX_OCCLUDED ) ) { frame.marker[DEX_NEGATIVE_BOX_MARKER].visibility = false; frame.marker[DEX_POSITIVE_BOX_MARKER].visibility = false; } else { frame.marker[DEX_NEGATIVE_BOX_MARKER].visibility = true; frame.marker[DEX_POSITIVE_BOX_MARKER].visibility = true; } // Map mouse coordinates to world coordinates. The factors used here are empirical. y = (double) ( mouse_position.y - rect.top ) / (double) ( rect.bottom - rect.top ); z = (double) (mouse_position.x - rect.right) / (double) ( rect.left - rect.right ); x = 0.0; // By default, the orientation of the manipulandum is the nominal orientation. CopyQuaternion( Q, nominalQ ); // Simulate wobbly movements of the manipulandum. This has not really been tested. if ( IsDlgButtonChecked( dlg, IDC_CODA_WOBBLY ) ) { // We will make the manipulandum rotate in a strange way as a function of the distance from 0. // This is just so that we can test the routines that compute the manipulandum position and orientation. double theta = y * 45.0; double gamma = - z * 45.0; SetQuaterniond( Ry, theta, iVector ); SetQuaterniond( Rz, gamma, jVector ); MultiplyQuaternions( midQ, Rz, nominalQ ); MultiplyQuaternions( Q, Ry, midQ ); // Make the movement a little bit in X as well so that we test the routines in 3D. x = 0.0 + 5.0 * sin( y / 80.0); } // Map screen position of the mouse pointer to 3D position of the wrist and manipulandum. // Top of the screen corresponds to the bottom of the bar and vice versa. It's inverted to protect the right hand rule. // Right of the screen correponds to the nearest horizontal target and left corresponds to the farthest. // The X position is set to be just to the right of the box. SubtractVectors( y_span, frame.marker[DEX_POSITIVE_BAR_MARKER].position, frame.marker[DEX_NEGATIVE_BAR_MARKER].position ); SubtractVectors( x_dir, frame.marker[DEX_POSITIVE_BOX_MARKER].position, frame.marker[DEX_NEGATIVE_BOX_MARKER].position ); NormalizeVector( x_dir ); ComputeCrossProduct( z_span, x_dir, y_span ); ScaleVector( y_displacement, y_span, y ); ScaleVector( z_displacement, z_span, z ); ScaleVector( x_displacement, x_dir, x ); // Reference position is the bottom target on the vertical target bar. CopyVector( position, frame.marker[DEX_NEGATIVE_BAR_MARKER].position ); // Place the manipulandum to the right of the box, even if the target bar is in the left position. position[X] = frame.marker[DEX_NEGATIVE_BOX_MARKER].position[X]; // Shift the position in X if the is any wobble to it. AddVectors( position, position, x_displacement ); // Shift the position in Y and Z according to the displacements computed from the mouse position. AddVectors( position, position, y_displacement ); AddVectors( position, position, z_displacement ); frame.time = DexTimerElapsedTime( acquisitionTimer ); // Displace the manipulandum with the mouse and make it rotate. for ( mrk = 0; mrk < nManipulandumMarkers; mrk++ ) { id = ManipulandumMarkerID[mrk]; RotateVector( rotated, Q, ManipulandumBody[mrk] ); AddVectors( frame.marker[id].position, position, rotated ); frame.marker[id].visibility = true; } // Displace the wrist with the mouse, but don't rotate it. for ( mrk = 0; mrk < nWristMarkers; mrk++ ) { id = WristMarkerID[mrk]; AddVectors( frame.marker[id].position, position, WristBody[mrk] ); frame.marker[id].visibility = true; } // Output the position and orientation used to compute the simulated // marker positions. This is for testing only. fprintf( fp, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", frame.time, position[X], position[Y], position[Z], Q[X], Q[Y], Q[Z], Q[M] ); return( true ); }
bool aimbot::BulletTrace(Vector src, Vector &dst, CBaseEntity* e) { bf->hTarget = e; ray r(src, dst); rt tr; trace->TraceRay(r, MASK_SHOT, bf, &tr); if (tr.fraction == 1.f) return 1; if (MENU_AUTOWALL) { if (css()) { WeaponInfo* w = lp->GetActiveWeapon()->GetWeaponInfo(); int penetration = w->CSS_GetPenetration(); float distance = w->CSS_GetDistance(); float range = w->CSS_GetRangeModifier(); float mindamage = (float)w->CSS_GetDamage() * 0.2f; float current_distance = 0.f, exit_distance = 0.f; float damage_mul = 5.f; float penetration_mul = 1.f; Vector direction = NormalizeVector(dst - src); rt wall; float p_distance, p_power; GetBulletTypeParameters(w->CSS_GetAmmoType(), p_power, p_distance); for (float current_damage = (float)w->CSS_GetDamage(); current_damage > mindamage;) { trace->TraceRay(ray(src, dst), MASK_SHOT, bf, &wall); if (wall.fraction == 1.f) return 1; surfacedata* sdata = physics->GetSurfaceData(wall.surfaceprops); int material = sdata->material; bool grate = wall.contents & 8; GetMaterialParameters(material, penetration_mul, damage_mul); if (grate) { penetration_mul = 1.0f; damage_mul = 0.99f; } current_distance += wall.fraction * distance; current_damage *= pow(range, (current_distance / 500.f)); if (current_distance > p_distance && penetration > 0) penetration = 0; if (penetration < 0 || penetration == 0 && !grate) break; Vector p_end; if (!Penetrate(exit_distance, wall.endpos, direction, p_end, 24.f, 128.f)) break; ray exit(p_end, wall.endpos); rt w_exit; trace->TraceRay(exit, MASK_SHOT, 0, &w_exit); if (w_exit.ent != wall.ent && w_exit.ent) { FilterGeneric skip1ent(w_exit.ent); trace->TraceRay(exit, MASK_SHOT, &skip1ent, &w_exit); } sdata = physics->GetSurfaceData(w_exit.surfaceprops); grate = grate && (w_exit.contents & 8); int e_material = sdata->material; if (material == e_material && (e_material == 0x57 || e_material == 0x4D)) penetration_mul *= 2.f; float trace_len = w_exit.endpos.DistTo(wall.endpos); if (trace_len > (p_power * penetration_mul)) break; src = w_exit.endpos; p_power -= trace_len / penetration_mul; current_distance += trace_len; current_damage *= damage_mul; distance = (distance - current_distance) * 0.5f; penetration--; } } } return 0; }
void Collision (ball * ballz) { ball *head = ballz; head = head->next; while (head) { if (IsHit (ballz, head)) { float dx, dy, w, h; float n_x, n_y; float hcx, hcy, bcx, bcy; float hdx, hdy, bdx, bdy; float impact_x, impact_y, impulse_x, impulse_y, impactSpeed; //Formula: // 1. Impact= balla-ballb 'vector subtaction // 2. impulse = Normalize(p1,p2) 'see normalize sub // 3. impactspeed = Dot!(impact,impulse) // 4. newimpulse=impulse*impactspeed*mass1*mass2 // 5. newa=balla+newimpulse/mass1 // 6. newb=ballb-newimpulse/mass2 // PS the divide by 2 is for the frictionless model. ;*) impact_x = head->delta_x - ballz->delta_x + 1; impact_y = head->delta_y - ballz->delta_y + 1; NormalizeVector (&impulse_x, &impulse_y, ballz->x, ballz->y, head->x, head->y); impactSpeed = DotVector (impact_x, impact_y, impulse_x, impulse_y) + 10; printf ("impact %f %f impulse %f %f %f \n", impact_x, impact_y, impulse_x, impulse_y, impactSpeed); impulse_x = impulse_x * impactSpeed * ballz->mass * head->mass / 2; impulse_y = impulse_y * impactSpeed * ballz->mass * head->mass / 2; printf ("impact %f %f impulse %f %f %f \n", impact_x, impact_y, impulse_x, impulse_y, impactSpeed); bdx = ballz->delta_x + impulse_x / ballz->mass; bdy = ballz->delta_y + impulse_y / ballz->mass; hdx = head->delta_x - impulse_x / head->mass; hdy = head->delta_y - impulse_y / head->mass; head->delta_x = bdx; head->delta_y = bdy; ballz->delta_x = hdx; ballz->delta_y = hdy; head->x += 2; head->y += 2; printf ("Impulse %f %f Impact %f %f head %d %d ballz %d %d - \n\n", impulse_x, impulse_y, impact_x, impact_y, head->delta_x, head->delta_y, ballz->delta_x, ballz->delta_y); //fflush(stdout); head->lasthit = ballz; ballz->lasthit = head; } else { if (ballz->lasthit == head->lasthit) { ballz->lasthit = NULL; head->lasthit = NULL; } } Collision (head); head = head->next; } }
void TScene::DrawRadarLabel(Vector pos) { // Draw Radar Slots glMatrixMode(GL_MODELVIEW); Vector col(0.25f,0.25f,0); // DrawLine2D(0.3f,0,0.7f,0,Vector(1,1,0)); DrawLine2D(0.7f,0,0.7f,0.3f,col); DrawLine2D(0.7f,0.3f,0.3f,0.3f,col); DrawLine2D(0.3f,0.3f,0.3f,0,col); DrawLine2D(0.3f,1,0.3f,0.7f,col); DrawLine2D(0.3f,0.7f,0.7f,0.7f,col); DrawLine2D(0.7f,0.7f,0.7f,1,col); Vector lskPos(0,0,0),lskPos2(0,0,0),tmpV(0,0,0); float tmp=0; OGLMath_VectorMatrixMultiply( lskPos, pos, Camera->CameraMatrix); lskPos2=lskPos; /* float mmodel[16]={0}; gluLookAt(0,0,0,dir.x,dir.y,dir.z,up.x,up.y,up.z); // glPushMatrix(); glGetFloatv(GL_MODELVIEW_MATRIX, mmodel); // glPopMatrix(); glLoadIdentity(); glTranslatef(pos.x, pos.y, pos.z); glMultTransposeMatrixf(mmodel);*/ //Camera->Apply(); float l=2000.0f-GetVectorLength(Camera->GetPosition()-pos); lskPos.x=lskPos.x/(3000.0f-l)+0.5f+0.35f; lskPos.y=lskPos.y/(3000.0f-l);//+0.5f; lskPos.z=-lskPos.z/(3000.0f-l)+0.5f-0.35f; if (lskPos.y>0.3f) lskPos.y=0.3f; if (lskPos.y<-0.3f) lskPos.y=-0.3f; DrawLine2D(lskPos.x, lskPos.z, lskPos.x, lskPos.z+lskPos.y, Vector(1,1,1)); DrawLine2D(lskPos.x, lskPos.z+lskPos.y, lskPos.x+0.01f, lskPos.z+lskPos.y, Vector(1,1,1)); DrawLine2D(0.85-0.01f,0.15,0.85+0.01f,0.15,Vector(1,1,1)); DrawLine2D(0.85,0.15-0.01f,0.85,0.15+0.01f,Vector(1,1,1)); // Draw Label of Sphere Radar float mmodel[16]={0}; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,10,0,2.3f,1,0,1,0); glGetFloatv(GL_MODELVIEW_MATRIX, mmodel); lskPos2=NormalizeVector(lskPos2)*1.2f; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMultMatrixf(ProjectionMatrix); glMultMatrixf(mmodel); glMatrixMode(GL_MODELVIEW); // tmpV=Camera->GetPosition(); // DrawLine(Vector(tmpV.x,tmpV.y,tmpV.z-1.0f),Vector(tmpV.x+50.0f,tmpV.y+50.0f,tmpV.z-100.0f), Vector(1,1,1)); // DrawLine(Vector(0,0,0),Vector(100,100,-100),Vector(1,1,1)); DrawLine(Vector(0,0,0),lskPos2,Vector(1,1,1)); // glBlendFunc(GL_SRC_ALPHA,GL_NONE); // Select The Type Of Blending // glEnable(GL_COLOR_MATERIAL); // glDisable(GL_LIGHTING); // glDisable(GL_LIGHT0); RenderPlanet(0.25f,Vector(0,0,0),6); // glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMultMatrixf(ProjectionMatrix); glMultMatrixf(Camera->CameraMatrix); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
int PixelColorShading(GzRender* render, GzCoord pixel_norm, GzColor pixel_color, GzColor pixel_tex, int flag) { GzCoord E = { 0.0, 0.0, -1.0 }; //Light GzCoord R; //Reflection //normarlize vector NormalizeVector(pixel_norm); float specular_component[3], diffuse_component[3], ambient_component[3]; for (int i = 0; i < 3; i++) { specular_component[i] = 0; diffuse_component[i] = 0; } float NE, NL, RE; for (int light_no = 0; light_no < render->numlights; light_no++) { NE = DOTPRODUCT_VECTOR(pixel_norm, E); NormalizeVector(render->lights[light_no].direction); NL = DOTPRODUCT_VECTOR(pixel_norm, render->lights[light_no].direction); //Both negative: flip normal and compute lighting model on backside of surface if (NE < 0 && NL < 0) { pixel_norm[X] *= -1; pixel_norm[Y] *= -1; pixel_norm[Z] *= -1; NE *= -1; NL *= -1; } //Each has different sign: light and eye are on opposite sides of the surface so the light contributes zero else if (NE * NL < 0) { continue; } //calculate Reflection, R = 2(N•L)N - L R[X] = 2 * NL * pixel_norm[X] - render->lights[light_no].direction[X]; R[Y] = 2 * NL * pixel_norm[Y] - render->lights[light_no].direction[Y]; R[Z] = 2 * NL * pixel_norm[Z] - render->lights[light_no].direction[Z]; NormalizeVector(R); RE = DOTPRODUCT_VECTOR(R, E); //RE calculations must be clamped to zero to maintain [0, 1] bounded range if (RE < 0) RE = 0; specular_component[RED] += render->lights[light_no].color[RED] * pow(RE, render->spec); specular_component[GREEN] += render->lights[light_no].color[GREEN] * pow(RE, render->spec); specular_component[BLUE] += render->lights[light_no].color[BLUE] * pow(RE, render->spec); diffuse_component[RED] += render->lights[light_no].color[RED] * NL; diffuse_component[GREEN] += render->lights[light_no].color[GREEN] * NL; diffuse_component[BLUE] += render->lights[light_no].color[BLUE] * NL; } if (flag == NON_TEXTURE) { pixel_color[RED] = render->Ks[RED] * specular_component[RED] + render->Kd[RED] * diffuse_component[RED] + render->Ka[RED] * render->ambientlight.color[RED]; pixel_color[GREEN] = render->Ks[GREEN] * specular_component[GREEN] + render->Kd[GREEN] * diffuse_component[GREEN] + render->Ka[GREEN] * render->ambientlight.color[GREEN]; pixel_color[BLUE] = render->Ks[BLUE] * specular_component[BLUE] + render->Kd[BLUE] * diffuse_component[BLUE] + render->Ka[BLUE] * render->ambientlight.color[BLUE]; } else if (flag == GOURAUD_TEXTURE) { pixel_color[RED] = specular_component[RED] + diffuse_component[RED] + render->ambientlight.color[RED]; pixel_color[GREEN] = specular_component[GREEN] + diffuse_component[GREEN] + render->ambientlight.color[GREEN]; pixel_color[BLUE] = specular_component[BLUE] + diffuse_component[BLUE] + render->ambientlight.color[BLUE]; } else if (flag == PHONG_TEXTURE) { pixel_color[RED] = render->Ks[RED] * specular_component[RED] + pixel_tex[RED] * diffuse_component[RED] + pixel_tex[RED] * render->ambientlight.color[RED]; pixel_color[GREEN] = render->Ks[GREEN] * specular_component[GREEN] + pixel_tex[GREEN] * diffuse_component[GREEN] + pixel_tex[GREEN] * render->ambientlight.color[GREEN]; pixel_color[BLUE] = render->Ks[BLUE] * specular_component[BLUE] + pixel_tex[BLUE] * diffuse_component[BLUE] + pixel_tex[BLUE] * render->ambientlight.color[BLUE]; } CHECK_OVERFLOW(pixel_color[RED]); CHECK_OVERFLOW(pixel_color[GREEN]); CHECK_OVERFLOW(pixel_color[BLUE]); return GZ_SUCCESS; }
/************************************************************************** MSHLib-Method: Task: Programing: 06/2005 WW Implementation **************************************************************************/ void CElem::FillTransformMatrix() { if(transform_tensor) return; double xx[3]; double yy[3]; double zz[3]; transform_tensor = new Math_Group::Matrix(3,3); if (geo_type == MshElemType::LINE) { // x"_vec double const* const pnt0(nodes[0]->getData()); double const* const pnt1(nodes[1]->getData()); xx[0] = pnt1[0] - pnt0[0]; xx[1] = pnt1[1] - pnt0[1]; xx[2] = pnt1[2] - pnt0[2]; NormalizeVector(xx, 3); // an arbitrary vector for (size_t i = 0; i < 3; i++) yy[i] = 0.0; //WW. 06.11.2007 if (fabs(xx[0]) > 0.0 && fabs(xx[1]) + fabs(xx[2]) < DBL_MIN) yy[2] = 1.0; else if (fabs(xx[1]) > 0.0 && fabs(xx[0]) + fabs(xx[2]) < DBL_MIN) yy[0] = 1.0; else if (fabs(xx[2]) > 0.0 && fabs(xx[0]) + fabs(xx[1]) < DBL_MIN) yy[1] = 1.0; else { for (size_t i = 0; i < 3; i++) if (fabs(xx[i]) > 0.0) { yy[i] = -xx[i]; break; } } // z"_vec CrossProduction(xx, yy, zz); NormalizeVector(zz, 3); // y"_vec CrossProduction(zz, xx, yy); NormalizeVector(yy, 3); } else if (geo_type == MshElemType::QUAD || geo_type == MshElemType::TRIANGLE) { // x"_vec // xx[0] = nodes[1]->X() - nodes[0]->X(); // xx[1] = nodes[1]->Y() - nodes[0]->Y(); // xx[2] = nodes[1]->Z() - nodes[0]->Z(); double const* const pnt0(nodes[0]->getData()); double const* const pnt1(nodes[1]->getData()); xx[0] = pnt1[0] - pnt0[0]; xx[1] = pnt1[1] - pnt0[1]; xx[2] = pnt1[2] - pnt0[2]; NormalizeVector(xx, 3); // a vector on the plane // yy[0] = nodes[2]->X() - nodes[1]->X(); // yy[1] = nodes[2]->Y() - nodes[1]->Y(); // yy[2] = nodes[2]->Z() - nodes[1]->Z(); double const* const pnt2(nodes[2]->getData()); yy[0] = pnt2[0] - pnt1[0]; yy[1] = pnt2[1] - pnt1[1]; yy[2] = pnt2[2] - pnt1[2]; // z"_vec. off plane CrossProduction(xx, yy, zz); NormalizeVector(zz, 3); // y"_vec CrossProduction(zz, xx, yy); NormalizeVector(yy, 3); } for (size_t i = 0; i < 3; i++) { (*transform_tensor)(i, 0) = xx[i]; (*transform_tensor)(i, 1) = yy[i]; (*transform_tensor)(i, 2) = zz[i]; } }
int CPhysEnv::CheckForCollisions( tParticle *system ) { // be optimistic! int collisionState = NOT_COLLIDING; float const depthEpsilon = 0.001f; int loop; tParticle *curParticle; m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS curParticle = system; for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); loop++,curParticle++) { // CHECK THE MAIN BOUNDARY PLANES FIRST for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && (collisionState != PENETRATING);planeIndex++) { tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; if(axbyczd < -depthEpsilon) { // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP collisionState = PENETRATING; } else if(axbyczd < depthEpsilon) { float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); if(relativeVelocity < 0.0f) { collisionState = COLLIDING; m_Contact[m_ContactCnt].particle = loop; memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); m_ContactCnt++; } } } if (m_CollisionActive) { // THIS IS NEW FROM MARCH - ADDED SPHERE BOUNDARIES // CHECK ANY SPHERE BOUNDARIES for(int sphereIndex = 0;(sphereIndex < m_SphereCnt) && (collisionState != PENETRATING);sphereIndex++) { tCollisionSphere *sphere = &m_Sphere[sphereIndex]; tVector distVect; VectorDifference(&curParticle->pos, &sphere->pos, &distVect); float radius = VectorSquaredLength(&distVect); // SINCE IT IS TESTING THE SQUARED DISTANCE, SQUARE THE RADIUS ALSO float dist = radius - (sphere->radius * sphere->radius); if(dist < -depthEpsilon) { // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP collisionState = PENETRATING; } else if(dist < depthEpsilon) { // NORMALIZE THE VECTOR NormalizeVector(&distVect); float relativeVelocity = DotProduct(&distVect,&curParticle->v); if(relativeVelocity < 0.0f) { collisionState = COLLIDING; m_Contact[m_ContactCnt].particle = loop; memcpy(&m_Contact[m_ContactCnt].normal,&distVect,sizeof(tVector)); m_ContactCnt++; } } } } } return collisionState; }
void Terrain::ComputeNormals() { float *norm1,*norm2,*norm3,*norm4; int i,j,k; if (normals == NULL) return; for(i = 0; i < length; i++) for(j = 0; j < width; j++) { norm1 = NULL; norm2 = NULL; norm3 = NULL; norm4 = NULL; if (i == 0 && j == 0) { norm1 = CrossProduct(0,0, 0,1, 1,0); NormalizeVector(norm1); } else if (j == width-1 && i == length-1) { norm1 = CrossProduct(i,j, j,i-1, j-1,i); NormalizeVector(norm1); } else if (j == 0 && i == length-1) { norm1 = CrossProduct(i,j, j,i-1, j+1,i); NormalizeVector(norm1); } else if (j == width-1 && i == 0) { norm1 = CrossProduct(i,j, j,i+1, j-1,i); NormalizeVector(norm1); } else if (i == 0) { norm1 = CrossProduct(j,0, j-1,0, j,1); NormalizeVector(norm1); norm2 = CrossProduct(j,0,j,1,j+1,0); NormalizeVector(norm2); } else if (j == 0) { norm1 = CrossProduct(0,i, 1,i, 0,i-1); NormalizeVector(norm1); norm2 = CrossProduct(0,i, 0,i+1, 1,i); NormalizeVector(norm2); } else if (i == length) { norm1 = CrossProduct(j,i, j,i-1, j+1,i); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j+1,i, j,i-1); NormalizeVector(norm2); } else if (j == width) { norm1 = CrossProduct(j,i, j,i-1, j-1,i); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j-1,i, j,i+1); NormalizeVector(norm2); } else { norm1 = CrossProduct(j,i, j-1,i, j,i+1); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j,i+1, j+1,i); NormalizeVector(norm2); norm3 = CrossProduct(j,i, j+1,i, j,i-1); NormalizeVector(norm3); norm4 = CrossProduct(j,i, j,i-1, j-1,i); NormalizeVector(norm4); } if (norm2 != NULL) { AddVector(norm1,norm2); free(norm2); } if (norm3 != NULL) { AddVector(norm1,norm3); free(norm3); } if (norm4 != NULL) { AddVector(norm1,norm4); free(norm4); } NormalizeVector(norm1); norm1[2] = - norm1[2]; for (k = 0; k< 3; k++) normals[3*(i*width + j) + k] = norm1[k]; free(norm1); } }
int GzBeginRender(GzRender *render) { /* - set up for start of each frame - init frame buffer */ if (NULL == render) return GZ_FAILURE; GzInitDisplay(render->display); //render->flatcolor[RED] = 0; //render->flatcolor[GREEN] = 0; //render->flatcolor[BLUE] = 0; /* perspective projection xform camera --> NDC*/ /*GzMatrix Xpi = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 / d, 0.0, 0.0, 0.0, 1.0 / d, 1.0 };*/ InitGzMatrix(render->camera.Xpi); render->camera.Xpi[2][2] = 1.0 / (1.0 / tan(DEGREE_TO_RADIAN(render->camera.FOV / 2.0))); // 1 /d render->camera.Xpi[3][2] = 1.0 / (1.0 / tan(DEGREE_TO_RADIAN(render->camera.FOV / 2.0))); // 1 /d /*GzMatrix Xiw = { Xx Xy Xz -X * C Yx Yy Yz -Y * C Zx Zy Zz -Z * C 0 0 0 1 */ InitGzMatrix(render->camera.Xiw); float norm; GzCoord Camera_X, Camera_Y, Camera_Z; //Camera_Z Camera_Z[X] = render->camera.lookat[X] - render->camera.position[X]; Camera_Z[Y] = render->camera.lookat[Y] - render->camera.position[Y]; Camera_Z[Z] = render->camera.lookat[Z] - render->camera.position[Z]; NormalizeVector(Camera_Z); NormalizeVector(render->camera.worldup); //Camera_Y // UP' = UP - (UP * Z) Z float sum_zaxis = (render->camera.worldup[X]) * Camera_Z[X] + (render->camera.worldup[Y]) * Camera_Z[Y] + (render->camera.worldup[Z]) * Camera_Z[Z]; Camera_Y[X] = render->camera.worldup[X] - sum_zaxis * Camera_Z[X]; Camera_Y[Y] = render->camera.worldup[Y] - sum_zaxis * Camera_Z[Y]; Camera_Y[Z] = render->camera.worldup[Z] - sum_zaxis * Camera_Z[Z]; NormalizeVector(Camera_Y); //Camera_X Camera_X[X] = Camera_Y[Y] * Camera_Z[Z] - Camera_Y[Z] * Camera_Z[Y]; Camera_X[Y] = Camera_Y[Z] * Camera_Z[X] - Camera_Y[X] * Camera_Z[Z]; Camera_X[Z] = Camera_Y[X] * Camera_Z[Y] - Camera_Y[Y] * Camera_Z[X]; render->camera.Xiw[0][0] = Camera_X[X]; render->camera.Xiw[0][1] = Camera_X[Y]; render->camera.Xiw[0][2] = Camera_X[Z]; render->camera.Xiw[0][3] = -(Camera_X[X] * render->camera.position[X] + Camera_X[Y] * render->camera.position[Y] + Camera_X[Z] * render->camera.position[Z]); render->camera.Xiw[1][0] = Camera_Y[X]; render->camera.Xiw[1][1] = Camera_Y[Y]; render->camera.Xiw[1][2] = Camera_Y[Z]; render->camera.Xiw[1][3] = -(Camera_Y[X] * render->camera.position[X] + Camera_Y[Y] * render->camera.position[Y] + Camera_Y[Z] * render->camera.position[Z]); render->camera.Xiw[2][0] = Camera_Z[X]; render->camera.Xiw[2][1] = Camera_Z[Y]; render->camera.Xiw[2][2] = Camera_Z[Z]; render->camera.Xiw[2][3] = -(Camera_Z[X] * render->camera.position[X] + Camera_Z[Y] * render->camera.position[Y] + Camera_Z[Z] * render->camera.position[Z]); GzPushMatrix(render, render->Xsp); //render->matlevel[1] GzPushMatrix(render, render->camera.Xpi); //render->matlevel[2] GzPushMatrix(render, render->camera.Xiw); //render->matlevel[3] return GZ_SUCCESS; }
/* Compute form-factors from the shooting patch to every elements */ static void ComputeFormfactors(unsigned long shootPatch) { unsigned long i; TVector3f up[5]; TPoint3f lookat[5]; TPoint3f center; TVector3f normal, tangentU, tangentV, vec; int face; double norm; TPatch* sp; double* fp; TElement* ep; double plane_eq[4]; /* get the center of shootPatch */ sp = &(params->patches[shootPatch]); center = sp->center; normal = sp->normal; plane_eq[0] = (double)normal.x; plane_eq[1] = (double)normal.y; plane_eq[2] = (double)normal.z; plane_eq[3] = (double)-(normal.x*center.x + normal.y*center.y + normal.z*center.z); /* rotate the hemi-cube along the normal axis of the patch randomly */ /* this will reduce the hemi-cube aliasing artifacts */ do { vec.x = RandomFloat; vec.y = RandomFloat; vec.z = RandomFloat; /* get a tangent vector */ CrossVector(tangentU, normal, vec); NormalizeVector(norm, tangentU); } while (norm==0); /* bad choice of the random vector */ /* compute tangentV */ CrossVector(tangentV, normal, tangentU); /* assign the lookats and ups for each hemicube face */ AddVector(lookat[0], center, normal); up[0] = tangentU; AddVector(lookat[1], center, tangentU); up[1] = normal; AddVector(lookat[2], center, tangentV); up[2] = normal; SubVector(lookat[3], center, tangentU); up[3] = normal; SubVector(lookat[4], center, tangentV); up[4] = normal; /* position the hemicube slightly above the center of the shooting patch */ ScaleVector(normal, params->worldSize*0.00000001); AddVector(hemicube.view.camera, center, normal); /* clear the formfactors */ fp = formfactors; for (i=params->nElements; i--; fp++) *fp = 0.0; for (face=0; face < 5; face++) { hemicube.view.lookat = lookat[face]; hemicube.view.up = up[face]; /* draw elements */ if (bits_for_RGB == 24) { /* a 24-bit display */ BeginHCDraw(&(hemicube.view), kBackgroundItem, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); } else if (bits_for_RGB == 8) { /* an 8-bit display */ /* this is a quick hack to make it work for 8-bit displays maybe a better way could be found ??? */ part_of_id = 1; /* processing first half of polygon ids */ BeginHCDraw(&(hemicube.view), 255, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); part_of_id = 2; /* second half of polygon ids */ BeginHCDraw(&(hemicube.view), 255, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); } else { printf("Unexpected bits per RGB colour, exiting"); //exit(0); } /* get formfactors */ if (face==0) SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.topFactors,0); else SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.sideFactors, hemicube.view.yRes/2); } /* compute reciprocal form-factors */ ep = params->elements; fp = formfactors; for (i=params->nElements; i--; ep++, fp++) { *fp *= sp->area / ep->area; /* This is a potential source of hemi-cube aliasing */ /* To do this right, we need to subdivide the shooting patch and reshoot. For now we just clip it to unity */ if ((*fp) > 1.0) *fp = 1.0; } }
void LMesh::CalcNormals(bool useSmoothingGroups) { uint i; // first calculate the face normals for (i=0; i<m_triangles.size(); i++) { LVector3 a, b; a = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].a])); b = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].c])); m_tris[i].normal = NormalizeVector(CrossProduct(b, a)); } std::vector< std::vector<int> > array; array.resize(m_vertices.size()); for (i=0; i<m_triangles.size(); i++) { uint k = m_tris[i].a; array[k].push_back(i); k = m_tris[i].b; array[k].push_back(i); k = m_tris[i].c; array[k].push_back(i); } LVector3 temp; if (!useSmoothingGroups) { // now calculate the normals without using smoothing groups for (i=0; i<m_vertices.size(); i++) { temp = zero3; int t = int(array[i].size()); for (int k=0; k<t; k++) { temp.x += m_tris[array[i][k]].normal.x; temp.y += m_tris[array[i][k]].normal.y; temp.z += m_tris[array[i][k]].normal.z; } m_normals[i] = NormalizeVector(temp); } } else { // now calculate the normals _USING_ smoothing groups // I'm assuming a triangle can only belong to one smoothing group at a time! std::vector<ulong> smGroups; std::vector< std::vector <uint> > smList; uint loop_size = uint(m_vertices.size()); for (i=0; i<loop_size; i++) { int t = uint(array[i].size()); if (t == 0) continue; smGroups.clear(); smList.clear(); smGroups.push_back(m_tris[array[i][0]].smoothingGroups); smList.resize(smGroups.size()); smList[smGroups.size()-1].push_back(array[i][0]); // first build a list of smoothing groups for the vertex for (int k=0; k<t; k++) { bool found = false; for (uint j=0; j<smGroups.size(); j++) { if (m_tris[array[i][k]].smoothingGroups == smGroups[j]) { smList[j].push_back(array[i][k]); found = true; } } if (!found) { smGroups.push_back(m_tris[array[i][k]].smoothingGroups); smList.resize(smGroups.size()); smList[smGroups.size()-1].push_back(array[i][k]); } } // now we have the list of faces for the vertex sorted by smoothing groups // now duplicate the vertices so that there's only one smoothing group "per vertex" if (smGroups.size() > 1) for (uint j=1; j< smGroups.size(); j++) { m_vertices.push_back(m_vertices[i]); m_normals.push_back(m_normals[i]); m_uv.push_back(m_uv[i]); m_tangents.push_back(m_tangents[i]); m_binormals.push_back(m_binormals[i]); uint ts = uint(m_vertices.size())-1; for (uint h=0; h<smList[j].size(); h++) { if (m_tris[smList[j][h]].a == i) m_tris[smList[j][h]].a = ts; if (m_tris[smList[j][h]].b == i) m_tris[smList[j][h]].b = ts; if (m_tris[smList[j][h]].c == i) m_tris[smList[j][h]].c = ts; } } } // now rebuild a face list for each vertex, since the old one is invalidated for (i=0; i<array.size(); i++) array[i].clear(); array.clear(); array.resize(m_vertices.size()); for (i=0; i<m_triangles.size(); i++) { uint k = m_tris[i].a; array[k].push_back(i); k = m_tris[i].b; array[k].push_back(i); k = m_tris[i].c; array[k].push_back(i); } // now compute the normals for (i=0; i<m_vertices.size(); i++) { temp = zero3; int t = uint(array[i].size()); for (int k=0; k<t; k++) { temp.x += m_tris[array[i][k]].normal.x; temp.y += m_tris[array[i][k]].normal.y; temp.z += m_tris[array[i][k]].normal.z; } m_normals[i] = NormalizeVector(temp); } } // copy m_tris to m_triangles for (i=0; i<m_triangles.size(); i++) { m_triangles[i].a = m_tris[i].a; m_triangles[i].b = m_tris[i].b; m_triangles[i].c = m_tris[i].c; } }
/* Compute form-factors from the shooting patch to every elements */ static void ComputeFormfactors(unsigned long shootPatch) { unsigned long i; TVector3f up[5]; TPoint3f lookat[5]; TPoint3f center; TVector3f normal, tangentU, tangentV, vec; int face; double norm; TPatch* sp; double* fp; TElement* ep; /* get the center of shootPatch */ sp = &(params->patches[shootPatch]); center = sp->center; normal = sp->normal; /* rotate the hemi-cube along the normal axis of the patch randomly */ /* this will reduce the hemi-cube aliasing artifacts */ do { vec.x = RandomFloat; vec.y = RandomFloat; vec.z = RandomFloat; /* get a tangent vector */ CrossVector(tangentU, normal, vec); NormalizeVector(norm, tangentU); } while (norm==0); /* bad choice of the random vector */ /* compute tangentV */ CrossVector(tangentV, normal, tangentU); /* assign the lookats and ups for each hemicube face */ AddVector(lookat[0], center, normal); up[0] = tangentU; AddVector(lookat[1], center, tangentU); up[1] = normal; AddVector(lookat[2], center, tangentV); up[2] = normal; SubVector(lookat[3], center, tangentU); up[3] = normal; SubVector(lookat[4], center, tangentV); up[4] = normal; /* position the hemicube slightly above the center of the shooting patch */ ScaleVector(normal, params->worldSize*0.0001); AddVector(hemicube.view.camera, center, normal); /* clear the formfactors */ fp = formfactors; for (i=params->nElements; i--; fp++) *fp = 0.0; for (face=0; face < 5; face++) { hemicube.view.lookat = lookat[face]; hemicube.view.up = up[face]; /* draw elements */ BeginDraw(&(hemicube.view), kBackgroundItem); for (i=0; i< params->nElements; i++) DrawElement(¶ms->elements[i], i); /* color element i with its index */ EndDraw(); /* get formfactors */ if (face==0) SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.topFactors); else SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes/2, hemicube.view.buffer, hemicube.sideFactors); } /* compute reciprocal form-factors */ ep = params->elements; fp = formfactors; for (i=params->nElements; i--; ep++, fp++) { *fp *= sp->area / ep->area; /* This is a potential source of hemi-cube aliasing */ /* To do this right, we need to subdivide the shooting patch and reshoot. For now we just clip it to unity */ if ((*fp) > 1.0) *fp = 1.0; } }
float CalcDiffractionLevel(SVector &svListener, SVector &svSource, SVector *psvPoint, long lPlaneType, SVector &svMin, SVector &svMax) { SVector svPoint = *psvPoint; float fHeight, fWidth; switch ( lPlaneType ) { case FRONT: case BACK: fHeight = svMax.fY - svPoint.fY; fWidth = svMax.fX - svPoint.fX; if ( fHeight < fWidth ) { fWidth = svPoint.fX - svMin.fX; if ( fHeight < fWidth ) { if ( fHeight < (svPoint.fY - svMin.fY) ) svPoint.fY = svMax.fY; else svPoint.fY = svMin.fY; } else if ( fWidth < (svPoint.fY - svMin.fY) ) svPoint.fX = svMin.fX; else svPoint.fY = svMin.fY; } else { fHeight = svPoint.fY - svMin.fY; if ( fWidth < fHeight ) { if ( fWidth < (svPoint.fX - svMin.fX) ) svPoint.fX = svMax.fX; else svPoint.fX = svMin.fX; } else if ( fHeight < (svPoint.fX - svMin.fX) ) svPoint.fY = svMin.fY; else svPoint.fX = svMin.fX; } break; case LEFT: case RIGHT: fHeight = svMax.fY - svPoint.fY; fWidth = svMax.fZ - svPoint.fZ; if ( fHeight < fWidth ) { fWidth = svPoint.fZ - svMin.fZ; if ( fHeight < fWidth ) { if ( fHeight < (svPoint.fY - svMin.fY) ) svPoint.fY = svMax.fY; else svPoint.fY = svMin.fY; } else if ( fWidth < (svPoint.fY - svMin.fY) ) svPoint.fZ = svMin.fZ; else svPoint.fY = svMin.fY; } else { fHeight = svPoint.fY - svMin.fY; if ( fWidth < fHeight ) { if ( fWidth < (svPoint.fZ - svMin.fZ) ) svPoint.fZ = svMax.fZ; else svPoint.fZ = svMin.fZ; } else if ( fHeight < (svPoint.fZ - svMin.fZ) ) svPoint.fY = svMin.fY; else svPoint.fZ = svMin.fZ; } break; case TOP: case BOTTOM: fHeight = svMax.fZ - svPoint.fZ; fWidth = svMax.fX - svPoint.fX; if ( fHeight < fWidth ) { fWidth = svPoint.fX - svMin.fX; if ( fHeight < fWidth ) { if ( fHeight < (svPoint.fZ - svMin.fZ) ) svPoint.fZ = svMax.fZ; else svPoint.fZ = svMin.fZ; } else if ( fWidth < (svPoint.fZ - svMin.fZ) ) svPoint.fX = svMin.fX; else svPoint.fZ = svMin.fZ; } else { fHeight = svPoint.fZ - svMin.fZ; if ( fWidth < fHeight ) { if ( fWidth < (svPoint.fX - svMin.fX) ) svPoint.fX = svMax.fX; else svPoint.fX = svMin.fX; } else if ( fHeight < (svPoint.fX - svMin.fX) ) svPoint.fZ = svMin.fZ; else svPoint.fX = svMin.fX; } break; default: return 0; } SVector svVec1; svVec1.fX = svListener.fX - svPoint.fX; svVec1.fY = svListener.fY - svPoint.fY; svVec1.fZ = svListener.fZ - svPoint.fZ; NormalizeVector(svVec1); SVector svVec2; svVec2.fX = svSource.fX - svPoint.fX; svVec2.fY = svSource.fY - svPoint.fY; svVec2.fZ = svSource.fZ - svPoint.fZ; NormalizeVector(svVec2); float fCos = svVec1.fX * svVec2.fX + svVec1.fY * svVec2.fY + svVec1.fZ * svVec2.fZ; return 1 - ((fCos + 1) / 2); }