void plActivatorBaseComponent::IGetReceivers(plMaxNode* node, hsTArray<plKey>& receivers) { // Add the guys who want to be notified by all instances ReceiverKeys::iterator lowIt = fReceivers.lower_bound(nil); ReceiverKeys::iterator highIt = fReceivers.upper_bound(nil); for (; lowIt != highIt; lowIt++) receivers.Append(lowIt->second); // Add the ones for just this instance lowIt = fReceivers.lower_bound(node); highIt = fReceivers.upper_bound(node); for (; lowIt != highIt; lowIt++) receivers.Append(lowIt->second); }
static void GetObjectPoints( plSceneObject *so, hsTArray<hsPoint3> &outPoints ) { const plDrawInterface* di = so->GetDrawInterface(); if( !di ) return; // The following uses mf's spiffy plAccessGeometry/Spans stuff, which, in // one uint16_t, kicksAss. hsTArray<plAccessSpan> spans; plAccessGeometry::Instance()->OpenRO( di, spans ); int i; outPoints.Reset(); for( i = 0; i < spans.GetCount(); i++ ) { plAccessVtxSpan& vtxSrc = spans[ i ].AccessVtx(); plAccPositionIterator iterSrc( &vtxSrc ); for( iterSrc.Begin(); iterSrc.More(); iterSrc.Advance() ) outPoints.Append( *iterSrc.Position() ); } if (plAccessGeometry::Instance()) plAccessGeometry::Instance()->Close( spans ); }
// Same thing, but returns multiple matches (see IFindAllBindingsByKey) void plKeyMap::FindAllBindingsByKey( const plKeyCombo &combo, hsTArray<const plKeyBinding*> &result ) const { hsTArray<plKeyBinding*> bindings; IFindAllBindingsByKey( combo, bindings ); int i; for (i = 0; i < bindings.GetCount(); i++) result.Append(bindings[i]); }
virtual bool EatPage( plRegistryPageNode *page ) { if ( !fAge.IsEmpty() && page->GetPageInfo().GetAge().CompareI(fAge) == 0 ) { fPages.Append( page ); } return true; }
virtual hsBool EatPage( plRegistryPageNode *page ) { if( fAge && stricmp( page->GetPageInfo().GetAge(), fAge ) == 0 ) { fPages.Append( page ); } return true; }
bool plAnimGroupedComponent::GetKeyList( INode *restrictedNode, hsTArray<plKey> &outKeys ) { if( fForward ) { outKeys.Append( fForward->GetKey() ); return true; } return false; }
bool plGeoSpanDice::IHalf(plGeometrySpan* src, hsTArray<plGeometrySpan*>& out, int exclAxis) const { if( !INeedSplitting(src) ) return false; int iAxis = ISelectAxis(exclAxis, src); // Ran out of axes to try. if( iAxis < 0 ) return false; float midPoint = src->fLocalBounds.GetCenter()[iAxis]; hsTArray<uint32_t> loTris; hsTArray<uint32_t> hiTris; uint16_t* indexData = src->fIndexData; int numTris = src->fNumIndices / 3; int stride = src->GetVertexSize(src->fFormat); int i; for( i = 0; i < numTris; i++ ) { hsPoint3& pos0 = *(hsPoint3*)(src->fVertexData + *indexData++ * stride); hsPoint3& pos1 = *(hsPoint3*)(src->fVertexData + *indexData++ * stride); hsPoint3& pos2 = *(hsPoint3*)(src->fVertexData + *indexData++ * stride); if( (pos0[iAxis] >= midPoint) &&(pos1[iAxis] >= midPoint) &&(pos2[iAxis] >= midPoint) ) { hiTris.Append(i); } else { loTris.Append(i); } } // This axis isn't working out, try another. if( !hiTris.GetCount() || !loTris.GetCount() ) return IHalf(src, out, exclAxis | (1 << iAxis)); plGeometrySpan* loDst = IExtractTris(src, loTris); plGeometrySpan* hiDst = IExtractTris(src, hiTris); delete src; out.Append(loDst); out.Append(hiDst); return true; }
void plMorphSequence::FindMorphMods(const plSceneObject *so, hsTArray<const plMorphSequence*> &mods) { const plMorphSequence *morph = plMorphSequence::ConvertNoRef(so->GetModifierByType(plMorphSequence::Index())); if (morph) mods.Append(morph); const plCoordinateInterface *ci = so->GetCoordinateInterface(); int i; for (i = 0; i < ci->GetNumChildren(); i++) FindMorphMods(ci->GetChild(i)->GetOwner(), mods); }
void plAnimStealthNode::GetAllStopPoints( hsTArray<float> &out ) { if( fCachedSegMap == nil ) return; for (SegmentMap::iterator it = fCachedSegMap->begin(); it != fCachedSegMap->end(); it++) { SegmentSpec *spec = it->second; if( spec->fType == SegmentSpec::kStopPoint ) { out.Append( spec->fStart ); } } }
void plDInputMgr::Init(HINSTANCE hInst, HWND hWnd) { HRESULT hr; hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&fDI->fDInput, NULL); hsAssert(!hr, "failed to initialize directInput!"); // enumerate game controllers Pfunc1 fPtr = &plDInputMgr::EnumGamepadCallback; int i = 0; // set up the action mapping fDI->fActionFormat = new DIACTIONFORMAT; fDI->fActionFormat->dwSize = sizeof(DIACTIONFORMAT); fDI->fActionFormat->dwActionSize = sizeof(DIACTION); fDI->fActionFormat->dwDataSize = NUM_ACTIONS * sizeof(DWORD); fDI->fActionFormat->dwNumActions = NUM_ACTIONS; fDI->fActionFormat->guidActionMap = PL_ACTION_GUID; fDI->fActionFormat->dwGenre = DIVIRTUAL_FIGHTING_THIRDPERSON; fDI->fActionFormat->rgoAction = fActionMap; fDI->fActionFormat->dwBufferSize = 16; fDI->fActionFormat->lAxisMin = -1000; fDI->fActionFormat->lAxisMax = 1000; sprintf( fDI->fActionFormat->tszActionMap, "Plasma 2.0 Game Actions" ); // this call should not work: fDI->fDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, fPtr, fDI, DIEDFL_ATTACHEDONLY); // apply the mapping to the game controller // this is the correct <but broken> way to apply the action map: // Pfunc3 fPtr3 = &plDInputMgr::EnumSuitableDevices; // hr = fDI->fDInput->EnumDevicesBySemantics(NULL, fDI->fActionFormat, EnumSuitableDevices, fDI, NULL); for (i = 0; i < fDI->fSticks.Count(); i++) { fDI->fSticks[i]->fCaps = new DIDEVCAPS; fDI->fSticks[i]->fCaps->dwSize = sizeof(DIDEVCAPS); hr = fDI->fSticks[i]->fDevice->GetCapabilities(fDI->fSticks[i]->fCaps); hsAssert(!hr, "Unable to acquire devcaps in DInput Device!"); hr = fDI->fSticks[i]->fDevice->Acquire(); hsAssert(!hr, "Unable to acquire DInput Device!"); } fhWnd = hWnd; for (i = 0; i < fDI->fSticks.Count(); i++) fInputDevice.Append( new plDInputDevice ); }
bool plAnimComponent::GetKeyList( INode *restrictedNode, hsTArray<plKey> &outKeys ) { if( restrictedNode != nil ) { if( fMods.find( (plMaxNode *)restrictedNode ) != fMods.end() ) { outKeys.Append( fMods[ (plMaxNode *)restrictedNode ]->GetKey() ); return true; } return false; } else { hsAssert( false, "DO SOMETHING!" ); return false; } }
void plInterMeshSmooth::FindSharedVerts(hsPoint3& searchPos, plSpanHandle& set, hsTArray<uint16_t>& edgeVerts, hsTArray<uint16_t>& shareVtx, hsVector3& normAccum) { int i; for( i = 0; i < edgeVerts.GetCount(); i++ ) { hsPoint3 pos = GetPosition(set, edgeVerts[i]); hsVector3 norm = GetNormal(set, edgeVerts[i]); if( searchPos == pos ) { if( norm.InnerProduct(normAccum) > fMinNormDot ) { shareVtx.Append(edgeVerts[i]); normAccum += norm; } } } }
static void ISearchLayerRecur( plLayerInterface *layer, const ST::string &segName, hsTArray<plKey>& keys ) { if( !layer ) return; plLayerAnimation *animLayer = plLayerAnimation::ConvertNoRef(layer); if (animLayer) { ST::string ID = animLayer->GetSegmentID(); if (!ID.compare(segName)) { if( keys.kMissingIndex == keys.Find(animLayer->GetKey()) ) keys.Append(animLayer->GetKey()); } } ISearchLayerRecur(layer->GetAttached(), segName, keys); }
// Find ALL bindings that could be triggered by this combo. Meaning that if we have multiple // bindings for a key with different shift/ctrl combinations, we want any that are satisfied with // the given combo. // We guarantee that the first binding in the result array is that one with priority. void plKeyMap::IFindAllBindingsByKey(const plKeyCombo &combo, hsTArray<plKeyBinding*> &result) const { uint32_t i; uint8_t bestScore = 0; for (i = 0; i < fBindings.GetCount(); i++) { hsBool s1, s2; s1 = fBindings[i]->GetKey1().IsSatisfiedBy(combo); s2 = fBindings[i]->GetKey2().IsSatisfiedBy(combo); if (s1 || s2) { uint8_t myScore = 0; if (s1) myScore = fBindings[i]->GetKey1().fFlags; if (s2 && (fBindings[i]->GetKey2().fFlags > myScore)) myScore = fBindings[i]->GetKey2().fFlags; if (myScore >= bestScore) result.Insert(0, fBindings[i]); else result.Append(fBindings[i]); } } }
void Add( plCommonObjLib *lib ) { fLibs.Append( lib ); fRefCount++; }
plMsgWrap& AddReceiver(const plKey& rcv) { hsAssert(rcv, "Trying to send mail to nil receiver"); fReceivers.Append(rcv); return *this; }
void plPipelineViewSettings::GetVisibleSpans(plDrawableSpans* drawable, hsTArray<int16_t>& visList, plVisMgr* visMgr) { static hsTArray<int16_t> tmpVis; tmpVis.SetCount(0); visList.SetCount(0); drawable->GetSpaceTree()->SetViewPos(GetViewPositionWorld()); drawable->GetSpaceTree()->Refresh(); if (fCullTreeDirty) RefreshCullTree(); const float viewDist = GetViewDirWorld().InnerProduct(GetViewPositionWorld()); const hsTArray<plSpan *> &spans = drawable->GetSpanArray(); plProfile_BeginTiming(Harvest); if (visMgr) { drawable->SetVisSet(visMgr); fCullTree.Harvest(drawable->GetSpaceTree(), tmpVis); drawable->SetVisSet(nullptr); } else { fCullTree.Harvest(drawable->GetSpaceTree(), tmpVis); } // This is a big waste of time, As a desparate "optimization" pass, the artists // insist on going through and marking objects to fade or pop out of rendering // past a certain distance. This breaks the batching and requires more CPU to // check the objects by distance. Since there is no pattern to the distance at // which objects will be told not to draw, there's no way to make this hierarchical, // which is what it would take to make it a performance win. So they succeed in // reducing the poly count, but generally the frame rate goes _down_ as well. // Unfortunately, this technique actually does work in a few key areas, so // I haven't been able to purge it. if (fPipeline->IsDebugFlagSet(plPipeDbg::kFlagSkipVisDist)) { int i; for (i = 0; i < tmpVis.GetCount(); i++) { if (spans[tmpVis[i]]->fSubType & fSubDrawableTypeMask) { visList.Append(tmpVis[i]); } } } else { int i; for (i = 0; i < tmpVis.GetCount(); i++) { if (spans[tmpVis[i]]->fSubType & fSubDrawableTypeMask) { // We'll check here for spans we can discard because they've completely distance faded out. // Note this is based on view direction distance (because the fade is), rather than the // preferrable distance to camera we sort by. float minDist, maxDist; if (drawable->GetSubVisDists(tmpVis[i], minDist, maxDist)) { const hsBounds3Ext& bnd = drawable->GetSpaceTree()->GetNode(tmpVis[i]).fWorldBounds; hsPoint2 depth; bnd.TestPlane(GetViewDirWorld(), depth); if ((0 < minDist + viewDist - depth.fY) ||(0 > maxDist + viewDist - depth.fX)) continue; } visList.Append(tmpVis[i]); } } } plProfile_EndTiming(Harvest); }
void plMorphSequence::SetWeight(int iLay, int iDel, float w, plKey meshKey /* = nil */) { int index = IFindSharedMeshIndex(meshKey); // Only dirty if the weight isn't for a pending mesh if(meshKey == nil || index >= 0) ISetDirty(true); if (meshKey == nil) { if( iLay < fMorphs.GetCount() ) { if( kMorphTime > 0 ) { plMorphTarget tgt; tgt.fLayer = iLay; tgt.fDelta = iDel; tgt.fWeight = w; fTgtWgts.Append(tgt); } else { fMorphs[iLay].SetWeight(iDel, w); } } } else if (index >= 0) { fSharedMeshes[index].fArrayWeights[iLay].fDeltaWeights[iDel] = w; fSharedMeshes[index].fFlags |= plSharedMeshInfo::kInfoDirtyMesh; if (index == fGlobalLayerRef) ISetAllSharedToGlobal(); } else { // Setting weight for a mesh we haven't added yet (loading state) index = IFindPendingStateIndex(meshKey); if (index < 0) { fPendingStates.Push(); index = fPendingStates.GetCount() - 1; fPendingStates[index].fSharedMeshKey = meshKey; } if (fPendingStates[index].fArrayWeights.GetCount() <= iLay) { int had = fPendingStates[index].fArrayWeights.GetCount(); hsTArray<plMorphArrayWeights> temp(iLay + 1); temp = fPendingStates[index].fArrayWeights; temp.SetCount(iLay + 1); fPendingStates[index].fArrayWeights.Swap(temp); int i; for( i = had; i < iLay+1; i++ ) fPendingStates[index].fArrayWeights[i].fDeltaWeights.Reset(); } if (fPendingStates[index].fArrayWeights[iLay].fDeltaWeights.GetCount() <= iDel) fPendingStates[index].fArrayWeights[iLay].fDeltaWeights.ExpandAndZero(iDel + 1); fPendingStates[index].fArrayWeights[iLay].fDeltaWeights[iDel] = w; } }
void pl3DPipeline::ICheckLighting(plDrawableSpans* drawable, hsTArray<int16_t>& visList, plVisMgr* visMgr) { if (fView.fRenderState & kRenderNoLights) return; if (!visList.GetCount()) return; plLightInfo* light; plProfile_BeginTiming(FindLights); // First add in the explicit lights (from LightGroups). // Refresh the lights as they are added (actually a lazy eval). plProfile_BeginTiming(FindPerm); for (size_t j = 0; j < visList.GetCount(); j++) { drawable->GetSpan(visList[j])->ClearLights(); if (IsDebugFlagSet(plPipeDbg::kFlagNoRuntimeLights)) continue; // Set the bits for the lights added from the permanent lists (during ClearLights()). const hsTArray<plLightInfo*>& permaLights = drawable->GetSpan(visList[j])->fPermaLights; for (size_t k = 0; k < permaLights.GetCount(); k++) { permaLights[k]->Refresh(); if (permaLights[k]->GetProperty(plLightInfo::kLPShadowLightGroup) && !permaLights[k]->IsIdle()) { // If it casts a shadow, attach the shadow now. ISetShadowFromGroup(drawable, drawable->GetSpan(visList[j]), permaLights[k]); } } const hsTArray<plLightInfo*>& permaProjs = drawable->GetSpan(visList[j])->fPermaProjs; for (size_t k = 0; k < permaProjs.GetCount(); k++) { permaProjs[k]->Refresh(); if (permaProjs[k]->GetProperty(plLightInfo::kLPShadowLightGroup) && !permaProjs[k]->IsIdle()) { // If it casts a shadow, attach the shadow now. ISetShadowFromGroup(drawable, drawable->GetSpan(visList[j]), permaProjs[k]); } } } plProfile_EndTiming(FindPerm); if (IsDebugFlagSet(plPipeDbg::kFlagNoRuntimeLights)) { plProfile_EndTiming(FindLights); return; } // Sort the incoming spans as either // A) moving - affected by all lights - moveList // B) specular - affected by specular lights - specList // C) visible - affected by moving lights - visList static hsTArray<int16_t> tmpList; static hsTArray<int16_t> moveList; static hsTArray<int16_t> specList; moveList.SetCount(0); specList.SetCount(0); plProfile_BeginTiming(FindSpan); for (size_t k = 0; k < visList.GetCount(); k++) { const plSpan* span = drawable->GetSpan(visList[k]); if (span->fProps & plSpan::kPropRunTimeLight) { moveList.Append(visList[k]); specList.Append(visList[k]); } else if (span->fProps & plSpan::kPropMatHasSpecular) { specList.Append(visList[k]); } } plProfile_EndTiming(FindSpan); // Make a list of lights that can potentially affect spans in this drawable // based on the drawables bounds and properties. // If the drawable has the PropCharacter property, it is affected by lights // in fCharLights, else only by the smaller list of fVisLights. plProfile_BeginTiming(FindActiveLights); static hsTArray<plLightInfo*> lightList; lightList.SetCount(0); if (drawable->GetNativeProperty(plDrawable::kPropCharacter)) { for (size_t i = 0; i < fCharLights.GetCount(); i++) { if (fCharLights[i]->AffectsBound(drawable->GetSpaceTree()->GetWorldBounds())) lightList.Append(fCharLights[i]); } } else { for (size_t i = 0; i < fVisLights.GetCount(); i++) { if (fVisLights[i]->AffectsBound(drawable->GetSpaceTree()->GetWorldBounds())) lightList.Append(fVisLights[i]); } } plProfile_EndTiming(FindActiveLights); // Loop over the lights and for each light, extract a list of the spans that light // affects. Append the light to each spans list with a scalar strength of how strongly // the light affects it. Since the strength is based on the object's center position, // it's not very accurate, but good enough for selecting which lights to use. plProfile_BeginTiming(ApplyActiveLights); for (size_t k = 0; k < lightList.GetCount(); k++) { light = lightList[k]; tmpList.SetCount(0); if (light->GetProperty(plLightInfo::kLPMovable)) { plProfile_BeginTiming(ApplyMoving); const hsTArray<int16_t>& litList = light->GetAffected(drawable->GetSpaceTree(), visList, tmpList, drawable->GetNativeProperty(plDrawable::kPropCharacter)); // PUT OVERRIDE FOR KILLING PROJECTORS HERE!!!! bool proj = nil != light->GetProjection(); if (fView.fRenderState & kRenderNoProjection) proj = false; for (size_t j = 0; j < litList.GetCount(); j++) { // Use the light IF light is enabled and // 1) light is movable // 2) span is movable, or // 3) Both the light and the span have specular const plSpan* span = drawable->GetSpan(litList[j]); bool currProj = proj; if (span->fProps & plSpan::kPropProjAsVtx) currProj = false; if (!(currProj && (span->fProps & plSpan::kPropSkipProjection))) { float strength, scale; light->GetStrengthAndScale(span->fWorldBounds, strength, scale); // We can't pitch a light because it's "strength" is zero, because the strength is based // on the center of the span and isn't conservative enough. We can pitch based on the // scale though, since a light scaled down to zero will have no effect no where. if (scale > 0) { plProfile_Inc(FindLightsFound); span->AddLight(light, strength, scale, currProj); } } } plProfile_EndTiming(ApplyMoving); } else if (light->GetProperty(plLightInfo::kLPHasSpecular)) { if (!specList.GetCount()) continue; plProfile_BeginTiming(ApplyToSpec); const hsTArray<int16_t>& litList = light->GetAffected(drawable->GetSpaceTree(), specList, tmpList, drawable->GetNativeProperty(plDrawable::kPropCharacter)); // PUT OVERRIDE FOR KILLING PROJECTORS HERE!!!! bool proj = nil != light->GetProjection(); if (fView.fRenderState & kRenderNoProjection) proj = false; for (size_t j = 0; j < litList.GetCount(); j++) { // Use the light IF light is enabled and // 1) light is movable // 2) span is movable, or // 3) Both the light and the span have specular const plSpan* span = drawable->GetSpan(litList[j]); bool currProj = proj; if (span->fProps & plSpan::kPropProjAsVtx) currProj = false; if (!(currProj && (span->fProps & plSpan::kPropSkipProjection))) { float strength, scale; light->GetStrengthAndScale(span->fWorldBounds, strength, scale); // We can't pitch a light because it's "strength" is zero, because the strength is based // on the center of the span and isn't conservative enough. We can pitch based on the // scale though, since a light scaled down to zero will have no effect no where. if (scale > 0) { plProfile_Inc(FindLightsFound); span->AddLight(light, strength, scale, currProj); } } } plProfile_EndTiming(ApplyToSpec); } else { if (!moveList.GetCount()) continue; plProfile_BeginTiming(ApplyToMoving); const hsTArray<int16_t>& litList = light->GetAffected(drawable->GetSpaceTree(), moveList, tmpList, drawable->GetNativeProperty(plDrawable::kPropCharacter)); // PUT OVERRIDE FOR KILLING PROJECTORS HERE!!!! bool proj = nil != light->GetProjection(); if (fView.fRenderState & kRenderNoProjection) proj = false; for (size_t j = 0; j < litList.GetCount(); j++) { // Use the light IF light is enabled and // 1) light is movable // 2) span is movable, or // 3) Both the light and the span have specular const plSpan* span = drawable->GetSpan(litList[j]); bool currProj = proj; if (span->fProps & plSpan::kPropProjAsVtx) currProj = false; if (!(currProj && (span->fProps & plSpan::kPropSkipProjection))) { float strength, scale; light->GetStrengthAndScale(span->fWorldBounds, strength, scale); // We can't pitch a light because it's "strength" is zero, because the strength is based // on the center of the span and isn't conservative enough. We can pitch based on the // scale though, since a light scaled down to zero will have no effect no where. if (scale > 0) { plProfile_Inc(FindLightsFound); span->AddLight(light, strength, scale, currProj); } } } plProfile_EndTiming(ApplyToMoving); } } plProfile_EndTiming(ApplyActiveLights); IAttachShadowsToReceivers(drawable, visList); plProfile_EndTiming(FindLights); }
// // wireframe debug draw method. // doesn't use any fancy subdivision or curvature measure when drawing. // Changes current time. // void plAnimPath::IMakeSegment(hsTArray<uint16_t>& idx, hsTArray<hsPoint3>& pos, hsPoint3& p1, hsPoint3& p2) { hsVector3 del(&p2, &p1); hsVector3 up; up.Set(0,0,1.f); const float kOutLength = 0.25f; hsVector3 a = del % up; float magSq = a.MagnitudeSquared(); if( magSq < 1.e-3f ) { a.Set(kOutLength, 0, 0); } else { a *= hsFastMath::InvSqrtAppr(magSq); a *= kOutLength; } hsVector3 b = a % del; hsFastMath::Normalize(b); b *= kOutLength; hsPoint3 p1out, p2out; int baseIdx = pos.GetCount(); pos.Append(p1); pos.Append(p2); p1out = p1; p1out += a; p2out = p2; p2out += a; pos.Append(p1out); pos.Append(p2out); p1out += -2.f * a; p2out += -2.f * a; pos.Append(p1out); pos.Append(p2out); p1out = p1; p1out += b; p2out = p2; p2out += b; pos.Append(p1out); pos.Append(p2out); p1out += -2.f * b; p2out += -2.f * b; pos.Append(p1out); pos.Append(p2out); int i; for( i = 0; i < 4; i++ ) { int outIdx = baseIdx + 2 + i * 2; idx.Append(baseIdx); idx.Append(baseIdx + 1); idx.Append(baseIdx + outIdx); idx.Append(baseIdx + outIdx); idx.Append(baseIdx + 1); idx.Append(baseIdx + outIdx + 1); } }
plCullNode::plCullStatus plCullNode::ISplitPoly(const plCullPoly& poly, plCullPoly*& innerPoly, plCullPoly*& outerPoly) const { static hsTArray<float> depths; depths.SetCount(poly.fVerts.GetCount()); static hsBitVector onVerts; onVerts.Clear(); hsBool someInner = false; hsBool someOuter = false; hsBool someOn = false; int i; for( i = 0; i < poly.fVerts.GetCount(); i++ ) { depths[i] = fNorm.InnerProduct(poly.fVerts[i]) + fDist; if( depths[i] < -kTolerance ) someInner = true; else if( depths[i] > kTolerance ) someOuter = true; else { someOn = true; onVerts.SetBit(i); } } if( !(someInner || someOuter) ) { (innerPoly = ScratchPolys().Push())->Init(poly); (outerPoly = ScratchPolys().Push())->Init(poly); return kSplit; } else if( !someInner ) { IMarkClipped(poly, onVerts); return kClear; } else if( !someOuter ) { IMarkClipped(poly, onVerts); return kCulled; } // Okay, it's split, now break it into the two polys (innerPoly = ScratchPolys().Push())->Init(poly); (outerPoly = ScratchPolys().Push())->Init(poly); static plCullPoly scrPoly; static hsBitVector inVerts; static hsBitVector outVerts; IBreakPoly(poly, depths, inVerts, outVerts, onVerts, scrPoly); static hsTArray<int> inPolyIdx; inPolyIdx.SetCount(0); static hsTArray<int> outPolyIdx; outPolyIdx.SetCount(0); for( i = 0; i < scrPoly.fVerts.GetCount(); i++ ) { if( inVerts.IsBitSet(i) ) { inPolyIdx.Append(i); } else if( outVerts.IsBitSet(i) ) { outPolyIdx.Append(i); } else { inPolyIdx.Append(i); outPolyIdx.Append(i); } } ITakeHalfPoly(scrPoly, inPolyIdx, onVerts, *innerPoly); ITakeHalfPoly(scrPoly, outPolyIdx, onVerts, *outerPoly); return kSplit; }
virtual int proc( ReferenceMaker *rmaker ) { fList.Append( rmaker ); return DEP_ENUM_CONTINUE; }
virtual void AddReceiverKey(plKey key, plMaxNode* node=nil) { fOthersKeys.Append(key); }
void plInterMeshSmooth::FindEdges(uint32_t maxVtxIdx, uint32_t nTris, uint16_t* idxList, hsTArray<uint16_t>& edgeVerts) { hsTArray<EdgeBin>* bins = new hsTArray<EdgeBin>[maxVtxIdx+1]; hsBitVector edgeVertBits; // For each vert pair (edge) in idxList int i; for( i = 0; i < nTris; i++ ) { int j; for( j = 0; j < 3; j++ ) { int jPlus = j < 2 ? j+1 : 0; int idx0 = idxList[i*3 + j]; int idx1 = idxList[i*3 + jPlus]; int lo, hi; // Look in the LUT for the lower index. if( idx0 < idx1 ) { lo = idx0; hi = idx1; } else { lo = idx1; hi = idx0; } hsTArray<EdgeBin>& loBin = bins[lo]; // In that bucket, look for the higher index. int k; for( k = 0; k < loBin.GetCount(); k++ ) { if( loBin[k].fVtx == hi ) break; } // If we find it, increment it's count, // else add it. if( k < loBin.GetCount() ) { loBin[k].fCount++; } else { EdgeBin* b = loBin.Push(); b->fVtx = hi; b->fCount = 1; } } } // For each bucket in the LUT, for( i = 0; i < maxVtxIdx+1; i++ ) { hsTArray<EdgeBin>& loBin = bins[i]; // For each higher index int j; for( j = 0; j < loBin.GetCount(); j++ ) { // If the count is one, it's an edge, so set the edge bit for both indices (hi and lo) if( 1 == loBin[j].fCount ) { edgeVertBits.SetBit(i); edgeVertBits.SetBit(loBin[j].fVtx); } } } // Now translate the bitvector to a list of indices. for( i = 0; i < maxVtxIdx+1; i++ ) { if( edgeVertBits.IsBitSet(i) ) edgeVerts.Append(i); } delete [] bins; }