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);
}
Esempio n. 2
0
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 );
}
Esempio n. 3
0
//  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]);
}
Esempio n. 4
0
        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;
        }
Esempio n. 6
0
bool    plAnimGroupedComponent::GetKeyList( INode *restrictedNode, hsTArray<plKey> &outKeys )
{
    if( fForward )
    {
        outKeys.Append( fForward->GetKey() );
        return true;
    }
    return false;
}
Esempio n. 7
0
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);
}
Esempio n. 9
0
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 );
        }
    }
}
Esempio n. 10
0
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 );
}
Esempio n. 11
0
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;
    }
}
Esempio n. 12
0
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;
            }
        }
    }
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
// 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]);
        }
    }
}
Esempio n. 15
0
 void    Add( plCommonObjLib *lib )
 {
     fLibs.Append( lib );
     fRefCount++;
 }
Esempio n. 16
0
 plMsgWrap&                      AddReceiver(const plKey& rcv) 
                                 { 
                                     hsAssert(rcv, "Trying to send mail to nil receiver");
                                     fReceivers.Append(rcv); return *this;
                                 }
Esempio n. 17
0
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;
    }
}
Esempio n. 19
0
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);
}
Esempio n. 20
0
//
// 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);
    }
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
 virtual int proc( ReferenceMaker *rmaker )
 {
     fList.Append( rmaker );
     return DEP_ENUM_CONTINUE;
 }
Esempio n. 23
0
 virtual void AddReceiverKey(plKey key, plMaxNode* node=nil) { fOthersKeys.Append(key); }
Esempio n. 24
0
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;
}