/// Passes the results of a test to the test suite callback function /// @param record Indicates whether or note the results of the test should be recorded to the results tree ctrl if the test was successful /// @param startTime The time when the test was started /// @param testName Name of the test /// @param success Indicates the success/failure of the test /// @param fileName Name of the file where the test occurred /// @param lineNumber Line number in the file where the test occurred bool TestSuite::Test(bool record, wxLongLong startTime, const wxChar* testName, bool success, char* fileName, size_t lineNumber) { //------Last Checked------// // - Dec 2, 2004 // Calculate the time to execute the test (in seconds) wxLongLong span = ::wxGetLocalTimeMillis() - startTime; double executionTime = ((double)span.ToLong()) / 1000.0; // If the test suite isn't being executed, bail out if (!IsExecuted()) return (false); // Update the success or failure of the test if (success) m_passed++; else m_failed++; wxCHECK(testName != NULL, false); wxCHECK(fileName != NULL, false); wxCHECK(m_testSuiteCallback != NULL, false); // Create a temp string used for the filename (since it's ANSI and we want it this to work on Unicode builds) wxString tempFileName(fileName); // Send the results of the test to the callback return (m_testSuiteCallback(this, testName, success, tempFileName, lineNumber, record, executionTime, m_clientData)); }
//------------------------------------------------------------------------------ // bool gosFX::Effect::HasFinished() { Check_Object(this); // //------------------------------------------------------------------------- // An effect is not finished if it is executing and its life hasn't expired //------------------------------------------------------------------------- // if (IsExecuted() && m_age < 1.0f) return false; // //----------------------------------------------- // It is also not finished if it has any children //----------------------------------------------- // Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children); return children.GetCurrent() == NULL; }
//------------------------------------------------------------------------------ // bool gosFX::Effect::Execute(ExecuteInfo *info) { Check_Object(this); Check_Pointer(info); Verify(IsExecuted()); gos_PushCurrentHeap(Heap); // //----------------------------------------------------- // If a new seed is provided, override the current seed //----------------------------------------------------- // if (info->m_seed != -1.0f) { Verify(info->m_seed>=0.0f && info->m_seed<1.0f); m_seed = info->m_seed; } // //-------------------------------------------- // Figure out the new age and clear the bounds //-------------------------------------------- // Stuff::Scalar age = m_age + static_cast<Stuff::Scalar>(info->m_time - m_lastRan) * m_ageRate; Verify(age >= 0.0f && age >= m_age); *info->m_bounds = Stuff::OBB::Identity; // //-------------------------------- // Update the effectToWorld matrix //-------------------------------- // Check_Object(info->m_parentToWorld); m_localToWorld.Multiply(m_localToParent, *info->m_parentToWorld); // //-------------------------------------------------- // Check to see if the top event needs to be handled //-------------------------------------------------- // Check_Object(m_specification); Event *event; while ((event = m_event.GetCurrent()) != NULL) { Check_Object(event); if (event->m_time > m_age) break; // //------------------------------------------------------------- // This event needs to go, so spawn and bump the effect pointer //------------------------------------------------------------- // unsigned flags = ExecuteFlag; if ((event->m_flags&SimulationModeMask) == ParentSimulationMode) { Verify((m_flags&SimulationModeMask) != ParentSimulationMode); flags |= m_flags&SimulationModeMask; } else flags |= event->m_flags&SimulationModeMask; Effect* effect = EffectLibrary::Instance->MakeEffect( event->m_effectID, flags ); Register_Object(effect); m_children.Add(effect); m_event.Next(); // //--------------------------------------------- // Now set the info for starting the new effect //--------------------------------------------- // effect->m_localToParent = event->m_localToParent; Stuff::Scalar min_seed = m_specification->m_minimumChildSeed.ComputeValue(m_age, m_seed); Stuff::Scalar seed_range = m_specification->m_maximumChildSeed.ComputeValue(m_age, m_seed) - min_seed; Stuff::Scalar seed = Stuff::Random::GetFraction()*seed_range + min_seed; Clamp(seed, 0.0f, 1.0f); ExecuteInfo local_info( info->m_time, &m_localToWorld, NULL, seed ); effect->Start(&local_info); } // //------------------------------------------------------------ // Execute all the children. If any of them finish, kill them //------------------------------------------------------------ // Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children); gosFX::Effect *child; Stuff::OBB child_obb = Stuff::OBB::Identity; ExecuteInfo child_info( info->m_time, &m_localToWorld, &child_obb ); child_info.m_bounds = &child_obb; while ((child = children.ReadAndNext()) != NULL) { Check_Object(child); if (!child->Execute(&child_info)) { Unregister_Object(child); delete child; } // //-------------------------------------------------------------- // Merge the bounding sphere of the child into the bounds of the // parent //-------------------------------------------------------------- // Stuff::OBB parent_bounds; parent_bounds.Multiply(child_obb, m_localToParent); info->m_bounds->Union(*info->m_bounds, parent_bounds); } Check_Object(info->m_bounds); // //---------------------------------------------------------------------- // Set the new time, then if we have run the course of the effect, start // over if we loop, otherwise wait for our children to finish before // killing ourselves //---------------------------------------------------------------------- // m_lastRan = info->m_time; m_age = age; if (m_age >= 1.0f) { if (IsLooped()) Start(info); else if (HasFinished()) Kill(); } // //---------------------------------- // Tell our parent if we need to die //---------------------------------- // gos_PopCurrentHeap(); return IsExecuted(); }
//------------------------------------------------------------------------------ // void gosFX::Effect::Start(ExecuteInfo *info) { Check_Object(this); Check_Pointer(info); gos_PushCurrentHeap(Heap); // //--------------------------------------------------------------------- // Don't override m_lastran if we are issuing a Start command while the // effect is already running //--------------------------------------------------------------------- // if (!IsExecuted() || m_lastRan == -1.0) m_lastRan = info->m_time; SetExecuteOn(); // //------------------------------------------- // If no seed was provided, pick one randomly //------------------------------------------- // m_seed = (info->m_seed == -1.0f) ? Stuff::Random::GetFraction() : info->m_seed; Verify(m_seed >= 0.0f && m_seed <= 1.0f); // //-------------------------------------------------------------------- // Figure out how long the emitter will live and its initial age based // upon the effect seed //-------------------------------------------------------------------- // Check_Object(m_specification); if (info->m_age == -1.0f) { Stuff::Scalar lifetime = m_specification->m_lifeSpan.ComputeValue(m_seed, 0.0f); Min_Clamp(lifetime, 0.033333f); m_ageRate = 1.0f / lifetime; m_age = 0; } else { m_age = info->m_age; m_ageRate = info->m_ageRate; Verify(m_age >= 0.0f && m_age <= 1.0f); } // //-------------------- // Set up the matrices //-------------------- // Check_Object(info->m_parentToWorld); m_localToWorld.Multiply(m_localToParent, *info->m_parentToWorld); // //------------------------- // Set up the event pointer //------------------------- // m_event.First(); gos_PopCurrentHeap(); }
//------------------------------------------------------------------------------ // bool gosFX::PointCloud::Execute(ExecuteInfo* info) { Check_Object(this); Check_Object(info); // //---------------------------------------- // If we aren't supposed to execute, don't //---------------------------------------- // if(!IsExecuted()) return false; // //------------------------------------------------------------------ // Animate the particles. If it is time for us to die, return false //------------------------------------------------------------------ // if(!ParticleCloud::Execute(info)) return false; // //----------------------------------------------------------------------- // If there are active particles to animate, get the current center point // of the bounds //----------------------------------------------------------------------- // if(m_activeParticleCount > 0) { Stuff::ExtentBox box(Stuff::Point3D::Identity, Stuff::Point3D::Identity); Stuff::Point3D* vertex = &m_P_localTranslation[0]; uint32_t i = 0; // //------------------------------------------------------------------- // If there is no bounds yet, we need to create our extent box around // the first legal point we find //------------------------------------------------------------------- // while(i < m_activeParticleCount) { Particle* particle = GetParticle(i); Check_Object(particle); if(particle->m_age < 1.0f) { Check_Object(vertex); box.maxX = vertex->x; box.minX = vertex->x; box.maxY = vertex->y; box.minY = vertex->y; box.maxZ = vertex->z; box.minZ = vertex->z; ++vertex; ++i; break; } ++vertex; ++i; } // //----------------------------- // Look for the other particles //----------------------------- // while(i < m_activeParticleCount) { Particle* particle = GetParticle(i); Check_Object(particle); if(particle->m_age < 1.0f) { Check_Object(vertex); if(vertex->x > box.maxX) box.maxX = vertex->x; else if(vertex->x < box.minX) box.minX = vertex->x; if(vertex->y > box.maxY) box.maxY = vertex->y; else if(vertex->y < box.minY) box.minY = vertex->y; if(vertex->z > box.maxZ) box.maxZ = vertex->z; else if(vertex->z < box.minZ) box.minZ = vertex->z; } ++vertex; ++i; } // //------------------------------------ // Now, build a info->m_bounds around this box //------------------------------------ // Verify(box.maxX >= box.minX); Verify(box.maxY >= box.minY); Verify(box.maxZ >= box.minZ); Stuff::OBB local_bounds = Stuff::OBB::Identity; local_bounds.axisExtents.x = 0.5f * (box.maxX - box.minX); local_bounds.axisExtents.y = 0.5f * (box.maxY - box.minY); local_bounds.axisExtents.z = 0.5f * (box.maxZ - box.minZ); local_bounds.localToParent(3, 0) = box.minX + local_bounds.axisExtents.x; local_bounds.localToParent(3, 1) = box.minY + local_bounds.axisExtents.y; local_bounds.localToParent(3, 2) = box.minZ + local_bounds.axisExtents.z; local_bounds.sphereRadius = local_bounds.axisExtents.GetLength(); if(local_bounds.sphereRadius < Stuff::SMALL) local_bounds.sphereRadius = 0.01f; Stuff::OBB parent_bounds; parent_bounds.Multiply(local_bounds, m_localToParent); info->m_bounds->Union(*info->m_bounds, parent_bounds); } // //---------------------------------------------- // Tell our caller that we get to keep executing //---------------------------------------------- // return true; }
//------------------------------------------------------------------------------ // bool gosFX::ParticleCloud::Execute(ExecuteInfo *info) { Check_Object(this); Check_Object(info); Verify(IsExecuted()); // //-------------------------------------------------------------------- // If we were given a new matrix, see if we have a parent. If so, // concatenate the two and figure out its inverse. If no parent, then // just invert the new matrix, otherwise just use the existing one //-------------------------------------------------------------------- // Stuff::LinearMatrix4D new_world_to_local; Stuff::LinearMatrix4D *matrix = NULL; int sim_mode = GetSimulationMode(); if (sim_mode == DynamicWorldSpaceSimulationMode) { Stuff::LinearMatrix4D local_to_world; local_to_world.Multiply(m_localToParent, *info->m_parentToWorld); new_world_to_local.Invert(local_to_world); matrix = &new_world_to_local; } // //-------------------------------------------------------- // Figure out the birth rate and request the new particles //-------------------------------------------------------- // Specification *spec = GetSpecification(); Check_Object(spec); Stuff::Scalar dT = static_cast<Stuff::Scalar>(info->m_time - m_lastRan); Verify(dT >= 0.0f); Stuff::Scalar prev_age = m_age; m_age += dT * m_ageRate; if (m_age >= 1.0f) m_birthAccumulator = 0.0f; else { Stuff::Scalar new_life = spec->m_particlesPerSecond.ComputeValue(m_age, m_seed); Min_Clamp(new_life, 0.0f); m_birthAccumulator += dT * new_life; } // //----------------------------------- // Deal with all the active particles //----------------------------------- // int i; int last_real = -1; for (i = 0; i < m_activeParticleCount; i++) { // //-------------------------------------------------------------------- // If the particle is active, age it and if it is not yet time to die, // go to the next particle, otherwise kill it //-------------------------------------------------------------------- // Particle *particle = GetParticle(i); Check_Object(particle); if (particle->m_age < 1.0f) { particle->m_age += dT*particle->m_ageRate; if (AnimateParticle(i, matrix, info->m_time)) { last_real = i; continue; } DestroyParticle(i); } // //-------------------------------------------------------------------- // If there are new particles to be born, go ahead and create them now //-------------------------------------------------------------------- // if (m_birthAccumulator >= 1.0f) { Stuff::Point3D translation; CreateNewParticle(i, &translation); if (AnimateParticle(i, matrix, info->m_time)) last_real = i; else DestroyParticle(i); m_birthAccumulator -= 1.0f; } } m_activeParticleCount = last_real + 1; // //---------------------------------------------------------------------- // If there are still new particles to be born, then we must try to grow // the active particle count //---------------------------------------------------------------------- // while ( m_birthAccumulator >= 1.0f && m_activeParticleCount < spec->m_maxParticleCount ) { i = m_activeParticleCount++; Stuff::Point3D translation; CreateNewParticle(i, &translation); if (!AnimateParticle(i, matrix, info->m_time)) { DestroyParticle(i); --m_activeParticleCount; } m_birthAccumulator -= 1.0f; } // //--------------------------------------------------------- // Only allow fractional births to carry over to next frame //--------------------------------------------------------- // m_birthAccumulator -= static_cast<Stuff::Scalar>(floor(m_birthAccumulator)); // //---------------------------- // Now let effect do its thing //---------------------------- // m_age = prev_age; return Effect::Execute(info); }
//------------------------------------------------------------------------------ // bool gosFX::Card::Execute(ExecuteInfo *info) { Check_Object(this); Check_Object(info); if (!IsExecuted()) return false; // //------------------------ // Do the effect animation //------------------------ // if (!Singleton::Execute(info)) return false; // //----------------------------------------- // Animate the parent then get our pointers //----------------------------------------- // Set_Statistic(Card_Count, Card_Count+1); Specification *spec = GetSpecification(); Check_Object(spec); // //---------------- // Animate the uvs //---------------- // Stuff::Scalar u = spec->m_UOffset.ComputeValue(m_age, m_seed); Stuff::Scalar v = spec->m_VOffset.ComputeValue(m_age, m_seed); Stuff::Scalar u2 = spec->m_USize.ComputeValue(m_age, m_seed); Stuff::Scalar v2 = spec->m_VSize.ComputeValue(m_age, m_seed); // //-------------------------------------------------------------- // If we are animated, figure out the row/column to be displayed //-------------------------------------------------------------- // if (spec->m_animated) { BYTE columns = Stuff::Truncate_Float_To_Byte( spec->m_index.ComputeValue(m_age, m_seed) ); BYTE rows = static_cast<BYTE>(columns / spec->m_width); columns = static_cast<BYTE>(columns - rows*spec->m_width); // //--------------------------- // Now compute the end points //--------------------------- // u += u2*columns; v += v2*rows; } u2 += u; v2 += v; m_uvs[0].x = u; m_uvs[0].y = v2; m_uvs[1].x = u2; m_uvs[1].y = v2; m_uvs[2].x = u2; m_uvs[2].y = v; m_uvs[3].x = u; m_uvs[3].y = v; // //------------------ // Fill in the color //------------------ // m_colors[0] = m_color; m_colors[1] = m_color; m_colors[2] = m_color; m_colors[3] = m_color; // //--------------------- // Fill in the position //--------------------- // m_vertices[0].x = m_scale*m_halfX; m_vertices[0].y = -m_scale*m_halfY; m_vertices[0].z = 0.0f; m_vertices[1].x = -m_scale*m_halfX; m_vertices[1].y = -m_scale*m_halfY; m_vertices[1].z = 0.0f; m_vertices[2].x = -m_scale*m_halfX; m_vertices[2].y = m_scale*m_halfY; m_vertices[2].z = 0.0f; m_vertices[3].x = m_scale*m_halfX; m_vertices[3].y = m_scale*m_halfY; m_vertices[3].z = 0.0f; return true; }