void SetRightClip() {Check_Pointer(this); clippingState |= RightClipFlag;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // gosFX::ComplexCurve::ComplexCurve(): Curve(e_ComplexType) { Check_Pointer(this); }
inline void* operator new(size_t size, void* where) {Check_Pointer(where); return where;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // gosFX::ComplexCurve::ComplexCurve(const ComplexCurve& fcurve): Curve(e_ComplexType) { Check_Pointer(this); m_keys = fcurve.m_keys; }
//--------------------------------------------------------------------------- // bool MLRIndexedPolyMesh::CastRay( Line3D *line, Normal3D *normal ) { Check_Object(this); Check_Object(line); Check_Pointer(normal); // //--------------------------------------------------------------------- // We have to spin through each of the polygons stored in the shape and // collide the ray against each //--------------------------------------------------------------------- // int poly_start = 0, numPrimitives = GetNumPrimitives(); bool hit = false; for (int polygon=0; polygon<numPrimitives; ++polygon) { int stride = lengths[polygon]; Verify(stride>2); // //--------------------------------- // See if the line misses the plane //--------------------------------- // Scalar product; const Plane *plane = &facePlanes[polygon]; Check_Object(plane); Scalar distance = line->DistanceTo(*plane, &product); if (distance < 0.0f || distance > line->length) { poly_start += stride; continue; } bool negate = false; if (product > -SMALL) { if (GetCurrentState().GetBackFaceMode() == MLRState::BackFaceOnMode) { poly_start += stride; continue; } negate = true; } // //------------------------------------------- // Figure out where on the plane the line hit //------------------------------------------- // Point3D impact; line->Project(distance, &impact); // //------------------------------------------------------------------- // We now need to find out which cardinal plane we should project the // triangle onto //------------------------------------------------------------------- // int s,t; Scalar nx = Abs(plane->normal.x); Scalar ny = Abs(plane->normal.y); Scalar nz = Abs(plane->normal.z); if (nx > ny) { if (nx > nz) { s = Y_Axis; t = Z_Axis; } else { s = X_Axis; t = Y_Axis; } } else if (ny > nz) { s = Z_Axis; t = X_Axis; } else { s = X_Axis; t = Y_Axis; } // //---------------------------------------- // Initialize the vertex and leg variables //---------------------------------------- // Point3D *v1, *v2, *v3; v1 = &coords[index[poly_start]]; v2 = &coords[index[poly_start+1]]; v3 = &coords[index[poly_start+2]]; // //--------------------------------------- // Get the projection of the impact point //--------------------------------------- // Scalar s0 = impact[s] - (*v1)[s]; Scalar t0 = impact[t] - (*v1)[t]; Scalar s1 = (*v2)[s] - (*v1)[s]; Scalar t1 = (*v2)[t] - (*v1)[t]; // //------------------------------------------------------------ // For each triangle, figure out what the second leg should be //------------------------------------------------------------ // bool local_hit = false; int next_v = 3; Test_Triangle: Check_Pointer(v3); Scalar s2 = (*v3)[s] - (*v1)[s]; Scalar t2 = (*v3)[t] - (*v1)[t]; // //-------------------------------- // Now, see if we hit the triangle //-------------------------------- // if (Small_Enough(s1)) { Verify(!Small_Enough(s2)); Scalar beta = s0 / s2; if (beta >= 0.0f && beta < 1.0f) { Verify(!Small_Enough(t1)); Scalar alpha = (t0 - beta*t2) / t1; local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f); } } else { Scalar beta = (t0*s1 - s0*t1); Scalar alpha = (t2*s1 - s2*t1); beta /= alpha; if (beta >= 0.0f && beta <= 1.0f) { alpha = (s0 - beta*s2) / s1; local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f); } } // //----------------------------- // Set up for the next triangle //----------------------------- // if (next_v < stride && !local_hit) { v2 = v3; v3 = &coords[index[poly_start+next_v++]]; s1 = s2; t1 = t2; goto Test_Triangle; } // //---------------------------------------------------- // Handle the hit status, and move to the next polygon //---------------------------------------------------- // if (local_hit) { hit = true; line->length = distance; if (negate) normal->Negate(plane->normal); else *normal = plane->normal; Verify(*normal * line->direction <= -SMALL); } poly_start += stride; } // //---------------------- // Return the hit status //---------------------- // return hit; }
bool IsLeftClipped() {Check_Pointer(this); return (clippingState&LeftClipFlag) != 0;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar Line3D::GetDistanceTo( const OBB& box, int *first_axis ) { Check_Object(this); Check_Object(&box); Check_Pointer(first_axis); // //------------------------------------------------------------------------ // Get the vector from the line to the centerpoint of the OBB. All planes // will be generated relative to this //------------------------------------------------------------------------ // Point3D center; center = box.localToParent; Vector3D delta; delta.Subtract(center, origin); // //-------------------------------------------------- // Set up the loop to examine each of the three axes //-------------------------------------------------- // Scalar enters = -100.0f - length; Scalar leaves = length + 100.0f; for (int axis=X_Axis; axis <= Z_Axis; ++axis) { UnitVector3D normal( box.localToParent(axis, X_Axis), box.localToParent(axis, Y_Axis), box.localToParent(axis, Z_Axis) ); // //---------------------------------------------------------------------- // Now, we have to calculate how far the line moves along the normal per // unit traveled down the line. If it is perpendicular to the normal, // then it will hit or miss based solely upon the origin location //---------------------------------------------------------------------- // Scalar drift = direction * normal; Scalar distance; if (Small_Enough(drift)) { distance = delta * normal; if (Fabs(distance) > box.axisExtents[axis]) return -1.0f; else continue; } // //-------------------------------------------------------------------- // We know the line is not parallel, so we will now calculate how long // the line will stay inside the box. We also will calculate how far // from the origin to the centerplane of the OBB //-------------------------------------------------------------------- // drift = 1.0f / drift; Scalar span = box.axisExtents[axis] * Fabs(drift); distance = (delta * normal) * drift; // //-------------------------------------------------------------------- // Now adjust where the line can enter and leave the OBB, and if it is // no longer possible to hit, stop checking //-------------------------------------------------------------------- // Scalar enter = distance - span; Scalar leave = distance + span; if (enter > enters) { *first_axis = axis; enters = enter; } if (leave < leaves) leaves = leave; if (enters > leaves) return -1.0f; } // //------------------------------------------------------------------------- // If we got here, then the line in theory can hit the OBB, so now we check // to make sure it hits it within the allowed span of the line //------------------------------------------------------------------------- // if (leaves < 0.0f || enters > length) return -1.0f; Min_Clamp(enters, 0.0f); return enters; }
bool operator!=(const MLRClippingState &s) { Check_Pointer(this); return (clippingState != s.clippingState); }
bool operator!=(const int &s) { Check_Pointer(this); return (clippingState != s); }
void SetClippingState(int state) {Check_Pointer(this); clippingState = state & ClipMask;}
int GetNumberOfSetBits() {Check_Pointer(this); Verify(clippingState<=ClipMask); return numberBitsLookUpTable[clippingState]; }
int GetClippingState() {Check_Pointer(this); return (clippingState & ClipMask);}
bool IsClipped(int mask) {Check_Pointer(this); return (clippingState & mask) != 0;}
void ClearRightClip() {Check_Pointer(this); clippingState &= ~RightClipFlag;}
void SetBottomClip() {Check_Pointer(this); clippingState |= BottomClipFlag;}
bool IsNearClipped() {Check_Pointer(this); return (clippingState&NearClipFlag) != 0;}
void ClearBottomClip() {Check_Pointer(this); clippingState &= ~BottomClipFlag;}
void SetNearClip() {Check_Pointer(this); clippingState |= NearClipFlag;}
//------------------------------------------------------------------------------ // bool gosFX::CardCloud::AnimateParticle( uint32_t index, const Stuff::LinearMatrix4D* world_to_new_local, Stuff::Time till ) { Check_Object(this); // //----------------------------------------- // Animate the parent then get our pointers //----------------------------------------- // if(!SpinningCloud::AnimateParticle(index, world_to_new_local, till)) return false; Set_Statistic(Card_Count, Card_Count + 1); Specification* spec = GetSpecification(); Check_Object(spec); Particle* particle = GetParticle(index); Check_Object(particle); float seed = particle->m_seed; float age = particle->m_age; // //------------------ // Animate the color //------------------ // Check_Pointer(m_P_color); m_P_color[index].red = spec->m_pRed.ComputeValue(age, seed); m_P_color[index].green = spec->m_pGreen.ComputeValue(age, seed); m_P_color[index].blue = spec->m_pBlue.ComputeValue(age, seed); m_P_color[index].alpha = spec->m_pAlpha.ComputeValue(age, seed); // //---------------- // Animate the uvs //---------------- // float u = spec->m_UOffset.ComputeValue(age, seed); float v = spec->m_VOffset.ComputeValue(age, seed); float u2 = spec->m_USize.ComputeValue(age, seed); float v2 = spec->m_VSize.ComputeValue(age, seed); // //-------------------------------------------------------------- // If we are animated, figure out the row/column to be displayed //-------------------------------------------------------------- // if(spec->m_animated) { uint8_t columns = Stuff::Truncate_Float_To_Byte( spec->m_pIndex.ComputeValue(age, seed) ); uint8_t rows = static_cast<uint8_t>(columns / spec->m_width); columns = static_cast<uint8_t>(columns - rows * spec->m_width); // //--------------------------- // Now compute the end points //--------------------------- // u += u2 * columns; v += v2 * rows; } u2 += u; v2 += v; index *= 4; m_P_uvs[index].x = u; m_P_uvs[index].y = v2; m_P_uvs[++index].x = u2; m_P_uvs[index].y = v2; m_P_uvs[++index].x = u2; m_P_uvs[index].y = v; m_P_uvs[++index].x = u; m_P_uvs[index].y = v; return true; }
void ClearNearClip() {Check_Pointer(this); clippingState &= ~NearClipFlag;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Scalar Line3D::GetDistanceTo( const Sphere &sphere, Scalar *penetration ) const { Check_Object(this); Check_Object(&sphere); Check_Pointer(penetration); // //------------------------------------------------------------------- // Determine if ray intersects bounding sphere of object. If sphere // is (X-C)*(X-C) = R^2 and ray is X = t*D+L for t >= 0, then // intersection is obtained by plugging X into sphere equation to // get quadratic: (D*D)t^2 + 2*(D*(L-C))t + (L-C)*(L-C) = 0 // Define a = D*D = 1.0f, b = 2*(D*(L-C)), and c = (L-C)*(L-C). //------------------------------------------------------------------- // Vector3D diff; diff.Subtract(origin, sphere.center); Scalar b = (direction*diff) * 2.0f; Scalar c = (diff*diff) - sphere.radius*sphere.radius; // //------------------------------------------------------------------------- // If penetration is negative, we couldn't hit the sphere at all. If it is // really small, it touches at only one place //------------------------------------------------------------------------- // *penetration = b*b - 4.0f*c; if (*penetration < -SMALL) { return -1.0f; } b *= -0.5f; if (*penetration<SMALL) { *penetration = 0.0f; Min_Clamp(b, 0.0f); return (b > length) ? -1.0f : b; } // //------------------------------------------------------------- // We know we hit the sphere, so figure out where it first hits //------------------------------------------------------------- // *penetration = 0.5f * Sqrt(*penetration); if (b + *penetration < -SMALL) { return -1.0f; } b -= *penetration; if (b > length) { return -1.0f; } Min_Clamp(b, 0.0f); return b; }
bool IsTopClipped() {Check_Pointer(this); return clippingState&TopClipFlag;}
void gosFX::Curve::ExpensiveComputeRange( float* low, float* hi, int32_t curvenum ) { Check_Object(this); Check_Pointer(low); Check_Pointer(hi); switch(m_type) { case e_ConstantType: { ConstantCurve* SCurve = (ConstantCurve*)this; SCurve->ComputeRange(low, hi); } break; case e_LinearType: { LinearCurve* SCurve = (LinearCurve*)this; SCurve->ComputeRange(low, hi); } break; case e_SplineType: { SplineCurve* SCurve = (SplineCurve*)this; SCurve->ComputeRange(low, hi); } break; case e_ComplexType: { ComplexCurve* SCurve = (ComplexCurve*)this; SCurve->ComputeRange(low, hi); } break; case e_ComplexLinearType: { SeededCurveOf<ComplexCurve, LinearCurve, Curve::e_ComplexLinearType>* SCurve = (SeededCurveOf<ComplexCurve, LinearCurve, Curve::e_ComplexLinearType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_ComplexComplexType: { SeededCurveOf<ComplexCurve, ComplexCurve, e_ComplexComplexType>* SCurve = (SeededCurveOf<ComplexCurve, ComplexCurve, e_ComplexComplexType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_ComplexSplineType: { SeededCurveOf<ComplexCurve, SplineCurve, e_ComplexSplineType>* SCurve = (SeededCurveOf<ComplexCurve, SplineCurve, e_ComplexSplineType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_ConstantComplexType: { SeededCurveOf<ConstantCurve, ComplexCurve, e_ConstantComplexType>* SCurve = (SeededCurveOf<ConstantCurve, ComplexCurve, e_ConstantComplexType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_ConstantLinearType: { SeededCurveOf<ConstantCurve, LinearCurve, e_ConstantLinearType>* SCurve = (SeededCurveOf<ConstantCurve, LinearCurve, e_ConstantLinearType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_ConstantSplineType: { SeededCurveOf<ConstantCurve, SplineCurve, e_ConstantSplineType>* SCurve = (SeededCurveOf<ConstantCurve, SplineCurve, e_ConstantSplineType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_SplineLinearType: { SeededCurveOf<SplineCurve, LinearCurve, e_SplineLinearType>* SCurve = (SeededCurveOf<SplineCurve, LinearCurve, e_SplineLinearType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; case e_SplineSplineType: { SeededCurveOf<SplineCurve, SplineCurve, e_SplineSplineType>* SCurve = (SeededCurveOf<SplineCurve, SplineCurve, e_SplineSplineType>*)this; if(curvenum == 0) SCurve->m_ageCurve.ComputeRange(low, hi); else SCurve->m_seedCurve.ComputeRange(low, hi); } break; default: break; } }
void SetTopClip() {Check_Pointer(this); clippingState |= TopClipFlag;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void gosFX::SplineCurve::ComputeRange( Stuff::Scalar *low, Stuff::Scalar *hi ) { Check_Object(this); Check_Pointer(low); Check_Pointer(hi); // //------------------------------------------------------------------------ // We know that we will have to test the function at the beginning and end // of the segment, so go ahead and do that now //------------------------------------------------------------------------ // *hi = *low = m_value; Stuff::Scalar t = ComputeValue(1.0f, 0.0f); if (t>*hi) *hi = t; else if (t<*low) *low = t; // //---------------------------------------------------------------------- // If the curve is not cubic, we just have to look for the local min/max // at the solution to 2*m_b*t + m_slope == 0. If the curve is linear, we just // return //---------------------------------------------------------------------- // if (!m_a) { if (m_b) { t = -0.5f * m_slope / m_b; if (t > 0.0f && t < 1.0f) { t = ComputeValue(t, 0.0f); if (t < *low) *low = t; else if (t > *hi) *hi = t; } } return; } // //---------------------------------------------------------------------- // Now we need to deal with the cubic. Its min/max will be at either of // the two roots of the equation 3*m_a*t*t + 2*m_b*t + m_slope == 0 //---------------------------------------------------------------------- // Stuff::Scalar da = 3.0f*m_a; Stuff::Scalar db = 2.0f*m_b; Stuff::Scalar range = db*db - 4.0f*da*m_slope; if (range < 0.0f) return; da = 0.5f / da; db = -db * da; range = Stuff::Sqrt(range) * da; // //------------------------------------------------------------------------ // db now holds the midpoint between the two solutions, which will be at + // or - range from that point //------------------------------------------------------------------------ // t = db - range; if (t > 0.0f && t < 1.0f) { t = ComputeValue(t, 0.0f); if (t < *low) *low = t; else if (t > *hi) *hi = t; } t = db + range; if (t > 0.0f && t < 1.0f) { t = ComputeValue(t, 0.0f); if (t < *low) *low = t; else if (t > *hi) *hi = t; } }
void ClearTopClip() {Check_Pointer(this); clippingState &= ~TopClipFlag;}
void gosFX::Curve::ExpensiveComputeRange( Stuff::Scalar *low, Stuff::Scalar *hi ) { Check_Object(this); Check_Pointer(low); Check_Pointer(hi); switch(m_type) { case e_ConstantType: { ConstantCurve *SCurve=(ConstantCurve *)this; SCurve->ComputeRange(low,hi); } break; case e_LinearType: { LinearCurve *SCurve=(LinearCurve *)this; SCurve->ComputeRange(low,hi); } break; case e_SplineType: { SplineCurve *SCurve=(SplineCurve *)this; SCurve->ComputeRange(low,hi); } break; case e_ComplexType: { ComplexCurve *SCurve=(ComplexCurve *)this; SCurve->ComputeRange(low,hi); } break; case e_ComplexLinearType: { SeededCurveOf<ComplexCurve, LinearCurve,Curve::e_ComplexLinearType> *SCurve=(SeededCurveOf<ComplexCurve, LinearCurve,Curve::e_ComplexLinearType> *)this; SCurve->ComputeRange(low,hi); } break; case e_ComplexComplexType: { SeededCurveOf<ComplexCurve, ComplexCurve,e_ComplexComplexType> *SCurve=(SeededCurveOf<ComplexCurve, ComplexCurve,e_ComplexComplexType> *)this; SCurve->ComputeRange(low,hi); } break; case e_ComplexSplineType: { SeededCurveOf<ComplexCurve, SplineCurve,e_ComplexSplineType> *SCurve=(SeededCurveOf<ComplexCurve, SplineCurve,e_ComplexSplineType> *)this; SCurve->ComputeRange(low,hi); } break; case e_ConstantComplexType: { SeededCurveOf<ConstantCurve,ComplexCurve,e_ConstantComplexType> *SCurve=(SeededCurveOf<ConstantCurve,ComplexCurve,e_ConstantComplexType> *)this; SCurve->ComputeRange(low,hi); } break; case e_ConstantLinearType: { SeededCurveOf<ConstantCurve,LinearCurve,e_ConstantLinearType> *SCurve=(SeededCurveOf<ConstantCurve,LinearCurve,e_ConstantLinearType> *)this; SCurve->ComputeRange(low,hi); } break; case e_ConstantSplineType: { SeededCurveOf<ConstantCurve,SplineCurve,e_ConstantSplineType> *SCurve=(SeededCurveOf<ConstantCurve,SplineCurve,e_ConstantSplineType> *)this; SCurve->ComputeRange(low,hi); } break; case e_SplineLinearType: { SeededCurveOf<SplineCurve,LinearCurve,e_SplineLinearType> *SCurve=(SeededCurveOf<SplineCurve,LinearCurve,e_SplineLinearType> *)this; SCurve->ComputeRange(low,hi); } break; case e_SplineSplineType: { SeededCurveOf<SplineCurve,SplineCurve,e_SplineSplineType> *SCurve=(SeededCurveOf<SplineCurve,SplineCurve,e_SplineSplineType> *)this; SCurve->ComputeRange(low,hi); } break; default: break; } }
bool IsBottomClipped() {Check_Pointer(this); return (clippingState&BottomClipFlag) != 0;}
inline void Is_Signature_Bad(const volatile void* p) {Check_Pointer(p);}
void ClearLeftClip() {Check_Pointer(this); clippingState &= ~LeftClipFlag;}