예제 #1
0
// ******************************************************************
// Rekursive Sichtbarkeitsberechnung
void tbOctree::ComputeVisibility(tbOctreeNode* pNode,
                                 tbPlane* pViewFrustum,
                                 tbVector3 vCamera,
                                 BOOL bDepthSort)
{
    // Wenn der Knoten unsichtbar ist, brechen wir sofort ab.
    if(!tbAABoxVisible(pNode->vBoundingBoxMin,
                       pNode->vBoundingBoxMax,
                       pViewFrustum)) return;

    if(pNode->bIsLeaf)
    {
        // Den Knoten als sichtbar eintragen
        m_ppVisibleList[m_dwNumLeavesVisible] = pNode;
        m_dwNumLeavesVisible++;

        // Wenn nach Tiefe sortiert werden soll, dann berechnen wir noch das
        // Quadrat der Entfernung der Mitte des Knotens zur Kamera.
        if(bDepthSort)
        {
            pNode->fDistSq = tbVector3LengthSq((0.5f * (pNode->vBoundingBoxMin + pNode->vBoundingBoxMax)) -
                                               vCamera);
        }
    }
    else
    {
        for(int i = 0; i < 8; i++)
        {
            // Sichtbarkeit dieses Unterknotens testen
            ComputeVisibility(pNode->apChild[i], pViewFrustum, vCamera, bDepthSort);
        }
    }
}
예제 #2
0
// ******************************************************************
// Diese Methode rendert den Octree.
tbResult tbOctree::Render(tbPlane* pViewFrustum,
                          tbVector3 vCamera,
                          int iFrom,				// = -1
                          int iTo,					// = -1
                          BOOL bRenderOpaque,		// = TRUE
                          BOOL bRenderAlphaBlended,	// = TRUE
                          BOOL bDepthSort)			// = TRUE
{
    HRESULT			hResult;
    DWORD			dwOldFVF;
    int				iNumPasses;
    tbOctreeNode*	pLeaf;


    // Parameter prüfen
    if(iFrom < -1 || iFrom >= (int)(m_dwNumEffects))	TB_ERROR_INVALID_VALUE("iFrom", TB_ERROR);
    if(iTo < -1 || iTo >= (int)(m_dwNumEffects))		TB_ERROR_INVALID_VALUE("iTo", TB_ERROR);


    // Werte anpassen
    if(iFrom == -1) iFrom = 0;
    if(iTo == -1) iTo = m_dwNumEffects - 1;

    // Sichtbarkeitsliste erstellen
    m_dwNumLeavesVisible = 0;
    ComputeVisibility(m_pRootNode, pViewFrustum, vCamera, bDepthSort);

    // Wenn erwünscht, nach Tiefe sortieren
    if(bDepthSort) qsort(m_ppVisibleList, m_dwNumLeavesVisible, sizeof(tbOctreeNode*), LeafCmpFunc);

    // Altes Vertexformat speichern
    dwOldFVF = tbDirect3D::GetFVF();

    // Vertexformat so wie Vertex- und Index-Buffer setzen
    tbDirect3D::SetFVF(m_dwFVF);
    tbDirect3D::GetDevice()->SetStreamSource(0, m_pVertexBuffer->GetVB(), 0, m_pVertexBuffer->GetVertexSize());
    tbDirect3D::GetDevice()->SetIndices(m_pIndexBuffer->GetIB());

    // Jeden Effekt durchgehen
    for(int iEffect = iFrom; iEffect <= iTo; iEffect++)
    {
        // Effekt aktivieren und alle Durchgänge rendern.
        // tbDirect3D::Capture wird später manuell aufgerufen.
        if(!m_pEffects[iEffect].Header.bAlphaBlended && bRenderOpaque ||
                m_pEffects[iEffect].Header.bAlphaBlended && bRenderAlphaBlended)
        {
            iNumPasses = m_pEffects[iEffect].pEffect->Begin(TRUE, FALSE);
            for(int iPass = 0; iPass < iNumPasses; iPass++)
            {
                // Durchgang aktivieren
                m_pEffects[iEffect].pEffect->BeginPass(iPass);

                // Die Sichtbarkeitsliste rendern
                for(DWORD dwLeaf = 0; dwLeaf < m_dwNumLeavesVisible; dwLeaf++)
                {
                    pLeaf = m_ppVisibleList[dwLeaf];
                    if(pLeaf->pdwEffectStart[iEffect] != 0xFFFFFFFF &&
                            pLeaf->pdwMinIndex[iEffect] != 0xFFFFFFFF &&
                            pLeaf->pdwMaxIndex[iEffect] != 0)
                    {
                        // Rendern
                        if(FAILED(hResult = tbDirect3D::GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
                                            0,
                                            pLeaf->pdwMinIndex[iEffect],
                                            pLeaf->pdwMaxIndex[iEffect] - pLeaf->pdwMinIndex[iEffect] + 1,
                                            pLeaf->pdwEffectStart[iEffect],
                                            (pLeaf->pdwEffectEnd[iEffect] - pLeaf->pdwEffectStart[iEffect]) / 3 + 1)))
                        {
                            // Fehler!
                            m_pEffects[iEffect].pEffect->End();
                            TB_ERROR_DIRECTX("tbDirect3D::GetDevice()->DrawIndexedPrimitive", hResult, TB_ERROR);
                        }
                    }
                    m_pEffects[iEffect].pEffect->EndPass();
                }
            }

            // Effekt deaktivieren
            m_pEffects[iEffect].pEffect->End();
        }
    }

    // Capture aufrufen, um die Tabellen in tbDirect3D zu aktualisieren
    tbDirect3D::Capture();

    // Das alte Vertexformat wieder setzen
    tbDirect3D::SetFVF(dwOldFVF);

    return TB_OK;
}
예제 #3
0
		virtual void ExportProcedural( AtNode *node )
		{
			// do basic node export
			
			ExportMatrix( node, 0 );
			
			AtNode *shader = arnoldShader();
			if( shader )
			{
				AiNodeSetPtr( node, "shader", shader );
			}
			
			AiNodeSetInt( node, "visibility", ComputeVisibility() );
			
			MPlug plug = FindMayaObjectPlug( "receiveShadows" );
			if( !plug.isNull() )
			{
				AiNodeSetBool( node, "receive_shadows", plug.asBool() );
			}
			
			plug = FindMayaObjectPlug( "aiSelfShadows" );
			if( !plug.isNull() )
			{
				AiNodeSetBool( node, "self_shadows", plug.asBool() );
			}
			
			plug = FindMayaObjectPlug( "aiOpaque" );
			if( !plug.isNull() )
			{
				AiNodeSetBool( node, "opaque", plug.asBool() );
			}
			
			// export any shading groups or displacement shaders which look like they
			// may be connected to procedural parameters. this ensures that maya shaders
			// the procedural will expect to find at rendertime will be exported to the
			// ass file (they otherwise might not be if they're not assigned to any objects).
			
			exportShadingInputs();
			
			// now set the procedural-specific parameters
			
			MFnDagNode fnDagNode( m_dagPath );
			MBoundingBox bound = fnDagNode.boundingBox();
			
			AiNodeSetPnt( node, "min", bound.min().x, bound.min().y, bound.min().z );
			AiNodeSetPnt( node, "max", bound.max().x, bound.max().y, bound.max().z );
			
			const char *dsoPath = getenv( "IECOREARNOLD_PROCEDURAL_PATH" );
			AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "ieProcedural.so" );
			
			AiNodeDeclare( node, "className", "constant STRING" );
			AiNodeDeclare( node, "classVersion", "constant INT" );
			AiNodeDeclare( node, "parameterValues", "constant ARRAY STRING" );
			
			// cast should be ok as we're registered to only work on procedural holders
			IECoreMaya::ProceduralHolder *pHolder = static_cast<IECoreMaya::ProceduralHolder *>( fnDagNode.userNode() );
			
			std::string className;
			int classVersion;
			IECore::ParameterisedProceduralPtr procedural = pHolder->getProcedural( &className, &classVersion );
			
			AiNodeSetStr( node, "className", className.c_str() );
			AiNodeSetInt( node, "classVersion", classVersion );
			
			IECorePython::ScopedGILLock gilLock;
			try
			{
				boost::python::object parser = IECoreMaya::PythonCmd::globalContext()["IECore"].attr( "ParameterParser" )();
				boost::python::object serialised = parser.attr( "serialise" )( procedural->parameters() );
				
				size_t numStrings = IECorePython::len( serialised );
				AtArray *stringArray = AiArrayAllocate( numStrings, 1, AI_TYPE_STRING );
				for( size_t i=0; i<numStrings; i++ )
				{
					std::string s = boost::python::extract<std::string>( serialised[i] );
					// hack to workaround ass parsing errors
					/// \todo Remove when we get the Arnold version that fixes this
					for( size_t c = 0; c<s.size(); c++ )
					{
						if( s[c] == '#' )
						{
							s[c] = '@';
						}
					}
					AiArraySetStr( stringArray, i, s.c_str() );
				}
				
				AiNodeSetArray( node, "parameterValues", stringArray );
			}
			catch( boost::python::error_already_set )
			{
				PyErr_Print();
			}
		
		}
                virtual void ExportProcedural( AtNode *node )
                {
                        // do basic node export
                        ExportMatrix( node, 0 );

                        // AiNodeSetPtr( node, "shader", arnoldShader(node) );


                        AiNodeSetInt( node, "visibility", ComputeVisibility() );

                        MPlug plug = FindMayaObjectPlug( "receiveShadows" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "receive_shadows", plug.asBool() );
                        }

                        plug = FindMayaObjectPlug( "aiSelfShadows" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "self_shadows", plug.asBool() );
                        }

                        plug = FindMayaObjectPlug( "aiOpaque" );
                        if( !plug.isNull() )
                        {
                                AiNodeSetBool( node, "opaque", plug.asBool() );
                        }

                        // now set the procedural-specific parameters

                        AiNodeSetBool( node, "load_at_init", true ); // just for now so that it can load the shaders at the right time

                        MFnDagNode fnDagNode( m_dagPath );
                        MBoundingBox bound = fnDagNode.boundingBox();

                        AiNodeSetPnt( node, "min", bound.min().x-m_dispPadding, bound.min().y-m_dispPadding, bound.min().z-m_dispPadding );
                        AiNodeSetPnt( node, "max", bound.max().x+m_dispPadding, bound.max().y, bound.max().z+m_dispPadding );

                        const char *dsoPath = getenv( "ALEMBIC_ARNOLD_PROCEDURAL_PATH" );
                        AiNodeSetStr( node, "dso",  dsoPath ? dsoPath : "bb_AlembicArnoldProcedural.so" );

                        // Set the parameters for the procedural

                        //abcFile path
                        MString abcFile = fnDagNode.findPlug("cacheFileName").asString().expandEnvironmentVariablesAndTilde();

                        //object path
                        MString objectPath = fnDagNode.findPlug("cacheGeomPath").asString();

                        //object pattern
                        MString objectPattern = "*";

                        plug = FindMayaObjectPlug( "objectPattern" );
                        if (!plug.isNull() )
                        {
                              if (plug.asString() != "")
                              {
                                objectPattern = plug.asString();
                              }
                        }

                        //object pattern
                        MString excludePattern = "";

                        plug = FindMayaObjectPlug( "excludePattern" );
                        if (!plug.isNull() )
                        {
                              if (plug.asString() != "")
                              {
                                excludePattern = plug.asString();
                              }
                        }

                        float shutterOpen = 0.0;
                        plug = FindMayaObjectPlug( "shutterOpen" );
                        if (!plug.isNull() )
                        {
                                shutterOpen = plug.asFloat();
                        }

                        float shutterClose = 0.0;
                        plug = FindMayaObjectPlug( "shutterClose" );
                        if (!plug.isNull() )
                        {
                                shutterClose = plug.asFloat();
                        }

                        float timeOffset = 0.0;
                        plug = FindMayaObjectPlug( "timeOffset" );
                        if (!plug.isNull() )
                        {
                                timeOffset = plug.asFloat();
                        }

                        int subDIterations = 0;
                        plug = FindMayaObjectPlug( "ai_subDIterations" );
                        if (!plug.isNull() )
                        {
                                subDIterations = plug.asInt();
                        }

                        MString nameprefix = "";
                        plug = FindMayaObjectPlug( "namePrefix" );
                        if (!plug.isNull() )
                        {
                                nameprefix = plug.asString();
                        }

                        // bool exportFaceIds = fnDagNode.findPlug("exportFaceIds").asBool();

                        bool makeInstance = true; // always on for now
                        plug = FindMayaObjectPlug( "makeInstance" );
                        if (!plug.isNull() )
                        {
                                makeInstance = plug.asBool();
                        }
                        
                        bool flipv = false; 
                        plug = FindMayaObjectPlug( "flipv" );
                        if (!plug.isNull() )
                        {
                                flipv = plug.asBool();
                        }

                        bool invertNormals = false; 
                        plug = FindMayaObjectPlug( "invertNormals" );
                        if (!plug.isNull() )
                        {
                                invertNormals = plug.asBool();
                        }
                        
                        short i_subDUVSmoothing = 1;
                        plug = FindMayaObjectPlug( "ai_subDUVSmoothing" );
                        if (!plug.isNull() )
                        {
                                i_subDUVSmoothing = plug.asShort();
                        }

                        MString  subDUVSmoothing;

                        switch (i_subDUVSmoothing)
                        {
                          case 0:
                            subDUVSmoothing = "pin_corners";
                            break;
                          case 1:
                            subDUVSmoothing = "pin_borders";
                            break;
                          case 2:
                            subDUVSmoothing = "linear";
                            break;
                          case 3:
                            subDUVSmoothing = "smooth";
                            break;
                          default :
                            subDUVSmoothing = "pin_corners";
                            break;
                        }

                        MTime curTime = MAnimControl::currentTime();
                        // fnDagNode.findPlug("time").getValue( frame );

                        // MTime frameOffset;
                        // fnDagNode.findPlug("timeOffset").getValue( frameOffset );

                        float time = curTime.as(MTime::kFilm)+timeOffset;

                        MString argsString;
                        if (objectPath != "|"){
                                argsString += "-objectpath ";
                                // convert "|" to "/"

                                argsString += MString(replace_all(objectPath,"|","/").c_str());
                        }
                        if (objectPattern != "*"){
                                argsString += "-pattern ";
                                argsString += objectPattern;
                        }
                        if (excludePattern != ""){
                                argsString += "-excludepattern ";
                                argsString += excludePattern;
                        }
                        if (shutterOpen != 0.0){
                                argsString += " -shutteropen ";
                                argsString += shutterOpen;
                        }
                        if (shutterClose != 0.0){
                                argsString += " -shutterclose ";
                                argsString += shutterClose;
                        }
                        if (subDIterations != 0){
                                argsString += " -subditerations ";
                                argsString += subDIterations;
                                argsString += " -subduvsmoothing ";
                                argsString += subDUVSmoothing;
                        }
                        if (makeInstance){
                                argsString += " -makeinstance ";
                        }
                        if (nameprefix != ""){
                                argsString += " -nameprefix ";
                                argsString += nameprefix;
                        }
                        if (flipv){
                                argsString += " -flipv ";
                        }
                        if (invertNormals){
                                argsString += " -invertNormals ";
                        }
                        argsString += " -filename ";
                        argsString += abcFile;
                        argsString += " -frame ";
                        argsString += time;

                        if (m_displaced){

                            argsString += " -disp_map ";
                            argsString += AiNodeGetName(m_dispNode);

                        }

                        AiNodeSetStr(node, "data", argsString.asChar());

                        ExportUserAttrs(node);

                        // Export light linking per instance
                        ExportLightLinking(node);

                }