コード例 #1
0
OP_ERROR
SOP_Ocean::cookMySop(OP_Context &context)
{
    float now = context.getTime();

    //std::cout << "cook ocean, t = " << now << std::endl;

    // lock inputs
    if (lockInputs(context) >= UT_ERROR_ABORT )
    {
        return error();
    }


    GEO_Point		*ppt;
    UT_Interrupt	*boss;

    // Check to see that there hasn't been a critical error in cooking the SOP.
    if (error() < UT_ERROR_ABORT)
    {
        boss = UTgetInterrupt();

        // Start the interrupt server
        boss->opStart("Updating Ocean");

        duplicatePointSource(0,context);

        int   gridres  = 1 << int(GRID_RES(now));
        float stepsize = GRID_SIZE(now) / (float)gridres;

        bool do_chop     = CHOP(now);
        bool do_jacobian = JACOBIAN(now);
        bool do_normals  = NORMALS(now) && !do_chop;

        if (!_ocean || _ocean_needs_rebuild)
        {
            if (_ocean)
            {
                delete _ocean;
            }

            if (_ocean_context)
            {
                delete _ocean_context;
            }

            _ocean = new drw::Ocean(gridres,gridres,stepsize,stepsize,
                                    V(0),L(0),1.0,W(0),1-DAMP(0),ALIGN(0),
                                    DEPTH(0),SEED(0));
            _ocean_scale   = _ocean->get_height_normalize_factor();

            _ocean_context = _ocean->new_context(true,do_chop,do_normals,do_jacobian);

            _ocean_needs_rebuild = false;
//             std::cout << "######### SOP, rebuilt ocean, norm_factor = " << _ocean_scale 
//                       << " chop = " << do_chop 
//                       << " norm = " << do_normals
//                       << " jacobian = " << do_jacobian
//                       << std::endl;
        }

        float chop_amount = CHOPAMOUNT(now);

        // sum up the waves at this timestep
        _ocean->update(TIME(now),*_ocean_context,true,do_chop,do_normals,do_jacobian,
                       _ocean_scale * SCALE(now),chop_amount);

        bool linterp = ! INTERP(now);


        // get our attribute indices
        GA_RWAttributeRef normal_index;
        GA_RWAttributeRef jminus_index;
        GA_RWAttributeRef eminus_index;

        if (do_normals)
        {
            normal_index = gdp->addNormalAttribute(GEO_POINT_DICT);
        }
        if (do_jacobian)
        {
            // jminus_index = gdp->addPointAttrib("mineigval",sizeof(float),GB_ATTRIB_FLOAT,0);
            // eminus_index = gdp->addPointAttrib("mineigvec",sizeof(UT_Vector3),GB_ATTRIB_VECTOR,0);
            jminus_index = gdp->addTuple(GA_STORE_REAL32,GA_ATTRIB_POINT,"mineigval",1,GA_Defaults(0));
            eminus_index = gdp->addFloatTuple(GA_ATTRIB_POINT,"mineigvec",1,GA_Defaults(0));
        }

        // this is not that fast, can it be done quicker ???
        GA_FOR_ALL_GPOINTS(gdp, ppt)
            {
                UT_Vector4 p = ppt->getPos();

                
                if (linterp)
                {
                    _ocean_context->eval_xz(p(0),p(2));
                }
                else
                {
                    _ocean_context->eval2_xz(p(0),p(2));
                }

                if (do_chop) 
                {
                    p.assign( p(0) + _ocean_context->disp[0],
                              p(1) + _ocean_context->disp[1],
                              p(2) + _ocean_context->disp[2] );
                }
                else
                {
                    // ppt->getPos()(1) += _ocean_context->disp[1];
                	UT_Vector4 tmp_p = ppt->getPos();
                	tmp_p(1) += _ocean_context->disp[1];
                	ppt->setPos(tmp_p);
                }

                if (do_normals)
                {
                	/*
					  UT_Vector3* normal = (UT_Vector3*) ppt->castAttribData<UT_Vector3>(normal_index);
					  normal->assign(_ocean_context->normal[0],
					                 _ocean_context->normal[1],
					                 _ocean_context->normal[2]);
					  normal->normalize();
                    */
                	ppt->getValue<UT_Vector3>(normal_index).assign(_ocean_context->normal[0],
																   _ocean_context->normal[1],
																   _ocean_context->normal[2]);
                	ppt->getValue<UT_Vector3>(normal_index).normalize();
                }

                if (do_jacobian)
                {/*
                    float *js = (float*)ppt->castAttribData<float>(jminus_index);
                    *js = _ocean_context->Jminus;
                    UT_Vector3* eminus = (UT_Vector3*)ppt->castAttribData<UT_Vector3>(eminus_index);
                    eminus->assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]);
                    */
                    ppt->setValue<float>(jminus_index,_ocean_context->Jminus);
                    ppt->getValue<UT_Vector3>(eminus_index).assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]);
                }
				ppt->setPos(p);
            }
コード例 #2
0
ファイル: aaOceanSOP.c プロジェクト: oyaGG/aaOcean
OP_ERROR aaOceanSOP::cookMySop(OP_Context &context)
{
    if (lockInputs(context) >= UT_ERROR_ABORT)
        return error();

    duplicateSource(0, context);
    setVariableOrder(3, 2, 0, 1);
    setCurGdh(0, myGdpHandle);
    setupLocalVars();

    // variable declarations
    float now  = context.getTime();

    // Flag the SOP as being time dependent (i.e. cook on time changes)
    flags().timeDep = 1;
    
    // start pulling in SOP inputs and send to aaOcean 
    enableEigens = (ENABLEEIGENS() != 0);
    if(pOcean->isChoppy() && enableEigens)
        enableEigens = TRUE;
    now = now + TIMEOFFSET(now);

    pOcean->input(  RESOLUTION(), 
                    SEED(),
                    OCEANSCALE(now),
                    OCEANDEPTH(now),
                    SURFACETENSION(now),
                    VELOCITY(now), 
                    CUTOFF(now), 
                    WINDDIR(now), 
                    WINDALIGN(), 
                    DAMP(now), 
                    WAVESPEED(now), 
                    WAVEHEIGHT(now),
                    CHOP(now), 
                    now,
                    LOOPTIME(now),
                    enableEigens,
                    FALSE);

    // get the user-specified attribute that holds uv-data
    getUVAttributeName(UvAttribute);
    if(UvAttribute.length() == 0)
        UvAttribute = "uv";
    const char* UVAttribName = (const char *)UvAttribute;
    uvRef = gdp->findFloatTuple(GA_ATTRIB_POINT, UVAttribName, 3);

    if(uvRef.isValid() == TRUE)
    {
        uvAttribute = uvRef.getAttribute();
        uvTuple = uvRef.getAIFTuple(); 
    }
    else
    {
        // uv attribute not found
        char msg[256];
        sprintf(msg, "[aaOcean] Specified UV attribute \'%s\' not found on geometry.\
                     \nUV's are required for aaOcean to cook", UVAttribName);
        std::cout<<msg;
        std::cout.flush();
        addError(SOP_MESSAGE, msg); 
        unlockInputs();
        return error();
    }

    // setup local variables to output Eigens
    if(enableEigens)
    {
        eVecPlusRef  = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecPlusName,    3);
        eVecMinusRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecMinusName,   3);
        eValuesRef   = gdp->addFloatTuple(GA_ATTRIB_POINT, eValuesName,     1);

        eVecPlusHandle  = GA_RWHandleV3(eVecPlusRef.getAttribute());
        eVecMinusHandle = GA_RWHandleV3(eVecMinusRef.getAttribute());
        eValuesHandle   = GA_RWHandleF(eValuesRef.getAttribute());
    }
    
    // inputs validated. Begin writing ocean data to output handles
    int npts = gdp->getNumPoints();
    #pragma omp parallel for 
    for (int pt_offset = 0; pt_offset < npts; ++pt_offset)
    {
        UT_Vector3F pos = gdp->getPos3(pt_offset);
        UT_Vector3F UV;
        
        uvTuple->get(uvAttribute, pt_offset, UV.data(), 3);
        // Houdini V coord runs in opposite direction compared to Softimage/Maya
        // Conforming with other apps to make ocean shape consistent across apps
        float u = UV.x();
        float v = 1.0f - (fmod(UV.y(), 1.0f));

        pos.y() += pOcean->getOceanData(u, v, aaOcean::eHEIGHTFIELD);
        if(pOcean->isChoppy())
        {
            pos.x() += pOcean->getOceanData(u, v, aaOcean::eCHOPX);
            pos.z() += pOcean->getOceanData(u, v, aaOcean::eCHOPZ);
        }
        gdp->setPos3(pt_offset, pos);

       if(enableEigens)
        {
            UT_Vector3F eigenVectorPlusValue;
            UT_Vector3F eigenVectorMinusValue;
            float eigenValue;

            eigenVectorPlusValue.x() =  pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSX);
            eigenVectorPlusValue.y() =  0.0f;
            eigenVectorPlusValue.z() =  pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSZ);

            eigenVectorMinusValue.x() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSX);
            eigenVectorMinusValue.y() = 0.0f;
            eigenVectorMinusValue.z() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSZ);

            eigenValue = pOcean->getOceanData(u, v, aaOcean::eFOAM);

            eVecPlusHandle.set(pt_offset,eigenVectorPlusValue);
            eVecMinusHandle.set(pt_offset,eigenVectorMinusValue);
            eValuesHandle.set(pt_offset,eigenValue);
        }
    }
    unlockInputs();

    return error();
}