Example #1
0
void AlembicPoints::ReadShapeFromOperator( IParticleGroup *particleGroup, PFSimpleOperator *pSimpleOperator, int particleId, TimeValue ticks, ShapeType &type, Abc::uint16_t &instanceId, float &animationTime)
{
	if(!pSimpleOperator){
		return;
	}

	if (pSimpleOperator->ClassID() == PFOperatorSimpleShape_Class_ID)
    {
        IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0);
        int nShapeId = pblock->GetInt(PFlow_kSimpleShape_shape, ticks);

        switch(nShapeId)
        {
        case PFlow_kSimpleShape_shape_pyramid:
            type = ShapeType_Cone;
            break;
        case PFlow_kSimpleShape_shape_cube:
            type = ShapeType_Box;
            break;
        case PFlow_kSimpleShape_shape_sphere:
            type = ShapeType_Sphere;
            break;
        case PFlow_kSimpleShape_shape_vertex:
            type = ShapeType_Point;
            break;
		default:
			type = ShapeType_Point;
        }
    }
	else if (pSimpleOperator->ClassID() == PFOperatorShapeLib_Class_ID)
	{
        IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0);
		int nDimension = pblock->GetInt(PFlow_kShapeLibary_dimensionType, ticks);
		if(nDimension == PFlow_kShapeLibrary_dimensionType_2D){
			int n2DShapeId = pblock->GetInt(PFlow_kShapeLibary_2DType, ticks);
			if( n2DShapeId == PFlow_kShapeLibrary_dimensionType_2D_square){
				type = ShapeType_Rectangle;
			}
			else{
				ESS_LOG_INFO("Unsupported shape type.");
				type = ShapeType_Point;
			}
		}
		else if(nDimension == PFlow_kShapeLibrary_dimensionType_3D){
			int n3DShapeId = pblock->GetInt(PFlow_kShapeLibary_3DType, ticks);
			if(n3DShapeId == PFlow_kShapeLibary_3DType_cube){
				type = ShapeType_Box;
			}
			else if(n3DShapeId == PFlow_kShapeLibary_3DType_Sphere20sides ||
					n3DShapeId == PFlow_kShapeLibary_3DType_Sphere80sides){
				type = ShapeType_Sphere;
			}
			else{
				ESS_LOG_INFO("Unsupported shape type.");
				type = ShapeType_Point;
			}
		
			//ShapeType_Cylinder unsupported
			//ShapeType_Cone unsupported
			//ShapeType_Disc unsupported
			//ShapeType_NbElements unsupported
		}
		else{
			ESS_LOG_INFO("Unknown dimension.");
			type = ShapeType_Point;
		}
			
		//int nNumParams = pblock->NumParams();

		//for(int i=0; i<nNumParams; i++){
	
		//	ParamID id = pblock->IndextoID(i);
		//	MSTR paramStr = pblock->GetLocalName(id, 0);
		//	int n = 0;
		//
		//}

	}
    else if (pSimpleOperator->ClassID() == PFOperatorInstanceShape_Class_ID)
    {
        // Assign animation time and shape here
        IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0);
        INode *pNode = pblock->GetINode(PFlow_kInstanceShape_objectMaxscript, ticks);
        if (pNode == NULL || pNode->GetName() == NULL)
        {
            return;
        }
        
        type = ShapeType_Instance;

		bool bFlatten = GetCurrentJob()->GetOption("flattenHierarchy");
		std::string nodePath = getNodeAlembicPath( EC_MCHAR_to_UTF8( pNode->GetName() ), bFlatten);

        // Find if the name is alerady registered, otherwise add it to the list
   //     instanceId = FindInstanceName(nodePath);
   //     if (instanceId == USHRT_MAX)
   //     {
			//mInstanceNames.push_back(nodePath);
   //         instanceId = (Abc::uint16_t)mInstanceNames.size()-1;
   //     }

        // Determine if we have an animated shape
        BOOL animatedShape = pblock->GetInt(PFlow_kInstanceShape_animatedShape);
	    BOOL acquireShape = pblock->GetInt(PFlow_kInstanceShape_acquireShape);

        if (!animatedShape && !acquireShape)
        {
            return;
        }

        // Get the necesary particle channels to grab the current time values
        ::IObject *pCont = particleGroup->GetParticleContainer();
        if (!pCont)
        {
            return;
        }

        // Get synch values that we are interested in fromt the param block
        int syncType = pblock->GetInt(PFlow_kInstanceShape_syncType);
        BOOL syncRandom = pblock->GetInt(PFlow_kInstanceShape_syncRandom);

        IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
        if (chTime == NULL) 
        {
            return; // can't find particle times in the container
        }

        IChannelContainer* chCont = GetChannelContainerInterface(pCont);
        if (chCont == NULL) 
        {
            return;  // can't get access to ChannelContainer interface
        }

        IParticleChannelPTVR* chBirthTime = NULL;
        IParticleChannelPTVR* chEventStartR = NULL;
        bool initEventStart = false;

        if (syncType == PFlow_kInstanceShape_syncBy_particleAge) 
        {
            chBirthTime = GetParticleChannelBirthTimeRInterface(pCont);
            if (chBirthTime == NULL) 
            {
                return; // can't read particle age
            }
        }
        else if (syncType == PFlow_kInstanceShape_syncBy_eventStart) 
        {
            chEventStartR = GetParticleChannelEventStartRInterface(pCont);
             
            if (chEventStartR == NULL) 
            {
                return; // can't read event start time
            }
        }

        IParticleChannelIntR* chLocalOffR = NULL;
        bool initLocalOff = false;

        // acquire LocalOffset particle channel; if not present then create it.
        if (syncRandom) 
        {
            chLocalOffR =  (IParticleChannelIntR*)chCont->GetPrivateInterface(PARTICLECHANNELLOCALOFFSETR_INTERFACE, pSimpleOperator);
        }

        // get new shape from the source
        PreciseTimeValue time = chTime->GetValue(particleId);
        switch(syncType)
        {
        case PFlow_kInstanceShape_syncBy_absoluteTime:
            break;
        case PFlow_kInstanceShape_syncBy_particleAge:
            time -= chBirthTime->GetValue(particleId);
            break;
        case PFlow_kInstanceShape_syncBy_eventStart:
            time -= chEventStartR->GetValue(particleId);
            break;
        default:
            break;
        }

        if (syncRandom) 
        {
            if (chLocalOffR != NULL)
                time += chLocalOffR->GetValue(particleId);
        }
		
		//timeValueMap::iterator it = mTimeValueMap.find(time);
		//if( it != mTimeValueMap.end() ){
		//	ESS_LOG_WARNING("sampleTime already seen.");
		//}
		//else{
		//	mTimeValueMap[time] = true;
		//	mTimeSamplesCount++;
		//	ESS_LOG_WARNING("sampleTime: "<<(float)time<<" totalSamples: "<<mTimeSamplesCount);
		//}

        TimeValue t = TimeValue(time);
        animationTime = (float)GetSecondsFromTimeValue(t);
    }
	else if (pSimpleOperator->ClassID() == PFOperatorMarkShape_Class_ID)
	{
		ESS_LOG_INFO("Shape Mark operator not supported.");
	}
	else if (pSimpleOperator->ClassID() == PFOperatorFacingShape_Class_ID)
	{
		ESS_LOG_INFO("Shape Facing operator not supported.");
	}

}
bool PFOperatorForceSpaceWarp::Proceed(IObject* pCont, 
									 PreciseTimeValue timeStart, 
									 PreciseTimeValue& timeEnd,
									 Object* pSystem,
									 INode* pNode,
									 INode* actionNode,
									 IPFIntegrator* integrator)
{
	// acquire all necessary channels, create additional if needed

	IChannelContainer* chCont;
	chCont = GetChannelContainerInterface(pCont);
	if (chCont == NULL) return false;

	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if(chAmount == NULL) return false;
	int iQuant = chAmount->Count();
	if (iQuant < 1) return true; // no particles to proceed

	IParticleChannelNewR* chNew = GetParticleChannelNewRInterface(pCont);
	if (chNew == NULL) return false; 

	IParticleChannelIDR* chID = GetParticleChannelIDRInterface(pCont);
	if (chID == NULL) return false;

	IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
	if(chTime == NULL) return false;

	IParticleChannelPTVR* chAge = GetParticleChannelBirthTimeRInterface(pCont);
	if(chAge == NULL) return false;

// the channel of interest speed
	bool initSpeed = false;
//channel does not exist so make it and note that we have to fill it out
	IParticleChannelPoint3W* chSpeedW = (IParticleChannelPoint3W*)chCont->EnsureInterface(PARTICLECHANNELSPEEDW_INTERFACE,
																			ParticleChannelPoint3_Class_ID,
																			true, PARTICLECHANNELSPEEDR_INTERFACE,
																			PARTICLECHANNELSPEEDW_INTERFACE, true,
																			actionNode, NULL, &initSpeed);
	IParticleChannelPoint3R* chSpeed = GetParticleChannelSpeedRInterface(pCont);
	if ((chSpeedW == NULL) || (chSpeed == NULL)) return false;

	bool initPosition = false;
	IParticleChannelPoint3W* chPosW = (IParticleChannelPoint3W*)chCont->EnsureInterface(PARTICLECHANNELPOSITIONW_INTERFACE,
																			ParticleChannelPoint3_Class_ID,
																			true, PARTICLECHANNELPOSITIONR_INTERFACE,
																			PARTICLECHANNELPOSITIONW_INTERFACE, true,
																			actionNode, NULL, &initPosition);
	IParticleChannelPoint3R* chPos = GetParticleChannelPositionRInterface(pCont);
	if ((chPosW == NULL) || (chPos == NULL)) return false;

	bool useScript = ((scriptPBlock()->GetInt(kForceSpaceWarp_useScriptWiring, 0) != 0)
						&& (scriptPBlock()->GetInt(kForceSpaceWarp_useFloat, 0) == kForceSpaceWarp_useFloat_influence));
	IParticleChannelFloatR* chFloat = NULL;
	if (useScript) {
		chFloat = GetParticleChannelMXSFloatRInterface(pCont);
		if (chFloat == NULL) return false;
	}

	int timeType = kAbsoluteTime;
	_pblock()->GetValue(kForceSpaceWarp_Sync,0, timeType, FOREVER);

	IParticleChannelPTVR* chEventStart = NULL;
	IParticleChannelPTVW* chEventStartW = NULL;
	bool initEventStart = false;
	if (timeType == kEventDuration)
	{
		chEventStartW = (IParticleChannelPTVW*) chCont->EnsureInterface(PARTICLECHANNELEVENTSTARTW_INTERFACE,
								  ParticleChannelPTV_Class_ID,
								  true, PARTICLECHANNELEVENTSTARTR_INTERFACE,
								  PARTICLECHANNELEVENTSTARTW_INTERFACE, false,
								  actionNode, NULL, &initEventStart);

		chEventStart = GetParticleChannelEventStartRInterface(pCont);
		if ((chEventStart == NULL) || (chEventStartW == NULL)) return false;
	}

	int overlapping = pblock()->GetInt(kForceSpaceWarp_Overlapping, 0);
	// collecting force fields
	Tab<ForceField*> ff;
	ForceField* curFF;
	int i, j;
	for(i=0; i<pblock()->Count(kForceSpaceWarp_ForceNodeList); i++) {
		INode* node = pblock()->GetINode(kForceSpaceWarp_ForceNodeList, 0, i);
		if (node == NULL) continue;
		Object* ob = GetPFObject(node->GetObjectRef());
		if (ob == NULL) continue;
		if (ob->SuperClassID() == WSM_OBJECT_CLASS_ID) {
			WSMObject* obref = (WSMObject*)ob;
			curFF = obref->GetForceField(node);
			if (curFF != NULL) {
				if (ob->ClassID() == CS_VFIELDOBJECT_CLASS_ID) {
					// CS VectorField SW doesn't init properly partobj on GetForceField
					// this is a quick fix for that (bayboro 3/6/2003)
					CS_VectorField* vf = (CS_VectorField*)curFF;
					vf->partobj = GetParticleInterface(pSystem);
				}
				ff.Append(1, &curFF);
			}
		}
	}
	if (ff.Count() == 0) return true; // no force fields

	// some calls for a reference node TM may initiate REFMSG_CHANGE notification
	// we have to ignore that while processing the particles
	bool wasIgnoring = IsIgnoringRefNodeChange();
	if (!wasIgnoring) SetIgnoreRefNodeChange();

	float influence = 0.0f;
	for(i = 0; i < iQuant; i++) 
	{
		TimeValue t = 0;
		if (timeType == kAbsoluteTime)
			t = chTime->GetValue(i).TimeValue();
		else if (timeType == kParticleAge)
			t = chTime->GetValue(i).TimeValue() - chAge->GetValue(i).TimeValue();
		else 
		{
			if (initEventStart && chNew->IsNew(i))
				chEventStartW->SetValue(i, chTime->GetValue(i));
			t = chTime->GetValue(i).TimeValue() - chEventStart->GetValue(i).TimeValue();
		}

		if (useScript) {
			influence = chFloat->GetValue(i);
		} else {
			influence = GetPFFloat(pblock(), kForceSpaceWarp_Influence, t);
		}

		Point3 v(0.0f,0.0f,0.0f);
		if (!initSpeed || !chNew->IsNew(i)) //if we created a speed channel the channel incoming is bogus so just use 0,0,0 ad default
			v = chSpeed->GetValue(i);

		Point3 p(0.0f,0.0f,0.0f);
		if (!initPosition || !chNew->IsNew(i)) //if we created a pos channel the channel incoming is bogus so just use 0,0,0 ad default
			p = chPos->GetValue(i);

		Point3 force = Point3::Origin;
		for(j=0; j<ff.Count(); j++) {
			// buffer vectors to guard true position and speed from malicious force
			Point3 pp = p;
			Point3 vv = v;
			Point3 nextForce = ff[j]->Force(t,pp,vv,chID->GetParticleBorn(i)) * influence;
			float lenSq = LengthSquared(nextForce);
			if (lenSq <= 0.0f) continue; // not a valid force
			if (overlapping == kForceSpaceWarp_Overlapping_additive) {
				force += nextForce;
			} else {
				if (lenSq > LengthSquared(force))
					force = nextForce;
			}
//			p = pp;
//			v = vv;
		}

		v += force * float(timeEnd - chTime->GetValue(i));
		chPosW->SetValue(i, p);
		chSpeedW->SetValue(i, v);
	}

	for(i=0; i<ff.Count(); i++)
		if (ff[i] != NULL) ff[i]->DeleteThis();

	if (!wasIgnoring) ClearIgnoreRefNodeChange();
	return true;
}