Пример #1
0
BOOL plDistributor::ISpaceClear(int iRepNode, const Matrix3& l2w, Box3& clearBox, plMeshCacheTab& cache) const
{
    if( !fDistTree )
        return true;

    // If we have high isolation,
    //      clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing));
    // Else if we have medium isolation
    //      clearBox = cache[iRepNode]->getBoundingBox(); // The mesh's bounds
    // Else if we have low isolation or None isolation
    //      clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); // kSmallSpace ~= 0.5f or one or something

    // We want to set up the box (for high, low and none) in Post OTM space. So instead of multiplying
    // by l2w, we want to multiply box = box * invOTM * l2w (because l2w already has OTM folded in). When using
    // the mesh bounds (Medium), l2w is the right transform.
    // objectTM = otm * nodeTM
    // invOTM * objectTM = nodeTM
    // invOTM = nodeTM * invObjectTM
    const float kSmallSpace = 0.5f;
    switch( fIsolation )
    {
    case kIsoHigh:
        {
            INode* repNode = fRepNodes[iRepNode];
            Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
            Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
            Matrix3 invOTM = nodeTM * Inverse(objectTM);
            clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0.f), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing));
            clearBox = clearBox * invOTM;
        }
        break;
    case kIsoMedium:
        clearBox = cache[iRepNode].fMesh->getBoundingBox(); // The mesh's bounds
        break;
    case kIsoLow:
    case kIsoNone:
    default:
        {
            INode* repNode = fRepNodes[iRepNode];
            Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
            Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
            Matrix3 invOTM = nodeTM * Inverse(objectTM);
            clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0.f), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); 
            clearBox = clearBox * invOTM;
        }
        break;
    }

    clearBox = clearBox * l2w;

    return fDistTree->BoxClear(clearBox, fFade);
}
Пример #2
0
static float CalcScale(INode *bone, NiNodeRef node, vector<NiNodeRef>& children)
{
   int n = bone->NumberOfChildren();
   if (n > 0) 
   {
      float len1 = 0.0f;
      float len2 = 0.0f;
      Matrix3 m = bone->GetNodeTM(0);
      Matrix3 m2 = TOMATRIX3(node->GetWorldTransform());
      for (int i = 0; i<n; i++)
      {
         INode *child = bone->GetChildNode(i);
         LPCTSTR name = child->GetName();
         if (HasBipedPosDOF(name))
            continue;

         Matrix3 cm = child->GetObjectTM(0);
         len1 += Length(m.GetTrans()-cm.GetTrans());

         if (NiNodeRef child2 = FindNodeByName(children, string(child->GetName()))){
            Matrix3 cm2 = TOMATRIX3(child2->GetWorldTransform());
            len2 += Length(m2.GetTrans()-cm2.GetTrans());
         }
      }
      return (len2 != 0.0f && len1 != 0.0f) ? (len2/len1) : 1.0f;
   }
   return 1.0f;
}
Пример #3
0
Point3 PBombField::Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index)
{	float d,chaos,dv;
	Point3 dlta,xb,yb,zb,center,expv;
	int decaytype,symm;
	Point3 zero=Zero;
		fValid = FOREVER;		
		if (!tmValid.InInterval(t)) 
		{	tmValid = FOREVER;
			tm = node->GetObjectTM(t,&tmValid);
			invtm = Inverse(tm);
		}
		xb=tm.GetRow(0);
		yb=tm.GetRow(1);
		zb=tm.GetRow(2);
		center=tm.GetTrans();
		fValid &= tmValid;
		TimeValue t0,t2,lastsfor;
		obj->pblock->GetValue(PB_STARTTIME,t,t0,fValid);
		obj->pblock->GetValue(PB_LASTSFOR,t,lastsfor,fValid);
		t2=t0+lastsfor;
		dlta=Zero;
		if ((t>=t0)&&(t<=t2))
		{ float L=Length(dlta=pos-center);
		  obj->pblock->GetValue(PB_DECAY,t,d,fValid);
		  obj->pblock->GetValue(PB_DECAYTYPE,t,decaytype,fValid);
		  if ((decaytype==0)||(L<=d))
		  { obj->pblock->GetValue(PB_DELTA_V,t,dv,fValid);
		    obj->pblock->GetValue(PB_CHAOS,t,chaos,fValid);
		    obj->pblock->GetValue(PB_SYMMETRY,t,symm,fValid);
		    Point3 r;
		    if (symm==SPHERE)
		      expv=(r=dlta/L);
	        else if (symm==PLANAR)
		    { L=DotProd(dlta,zb);
			  expv=(L<0.0f?L=-L,-zb:zb);
		    }
		    else
		    { Point3 E;
		      E=DotProd(dlta,xb)*xb+DotProd(dlta,yb)*yb;
		      L=Length(E);
		      expv=E/L;
		    }
		    dlta=(dv*expv)/(float)dtsq;
			if (decaytype==1)
			 dlta*=(d-L)/d;
			else if (decaytype==2)
			 dlta*=(1/(float)exp(L/d));
			if ((!FloatEQ0(chaos))&&(lastsfor==0.0f))
			{ float theta;
			  theta=HalfPI*chaos*RND01();
			  // Martell 4/14/01: Fix for order of ops bug.
			  float ztmp=RND11(); float ytmp=RND11(); float xtmp=RND11();
			  Point3 d=Point3(xtmp,ytmp,ztmp);
			  Point3 c=Normalize(dlta^d);
			  RotateOnePoint(&dlta.x,&zero.x,&c.x,theta);
			}
		  }	else dlta=Zero; 
		}
	return dlta;
	}
Пример #4
0
//=================================================================
// Methods for CollectNodesTEP
//
int CollectNodesTEP::callback(INode *node)
{
	INode *pnode = node; // Hungarian

	ASSERT_MBOX(!(pnode)->IsRootNode(), "Encountered a root node!");

	if (::FNodeMarkedToSkip(pnode))
		return TREE_CONTINUE;

	// Get pre-stored "index"
	int iNode = ::GetIndexOfINode(pnode);
	ASSERT_MBOX(iNode >= 0 && iNode <= m_phec->m_imaxnodeMac-1, "Bogus iNode");
	
	// Get name, store name in array
	TSTR strNodeName(pnode->GetName());
	strcpy(m_phec->m_rgmaxnode[iNode].szNodeName, (char*)strNodeName);

	// Get Node's time-zero Transformation Matrices
	m_phec->m_rgmaxnode[iNode].mat3NodeTM		= pnode->GetNodeTM(0/*TimeValue*/);
	m_phec->m_rgmaxnode[iNode].mat3ObjectTM		= pnode->GetObjectTM(0/*TimeValue*/);

	// I'll calculate this later
	m_phec->m_rgmaxnode[iNode].imaxnodeParent	= SmdExportClass::UNDESIRABLE_NODE_MARKER;

	return TREE_CONTINUE;
}
Пример #5
0
void PolyOpExtrudeAlongSpline::GetValues (IParamBlock2 *pblock, TimeValue t, Interval & ivalid)
{
	PolyOperation::GetValues (pblock, t, ivalid);

	// Special case for the spline & transform.
	if (!mSplineValidity.InInterval (t))
	{
		mSplineValidity.SetInfinite ();
		INode *pSplineNode;
		pblock->GetValue (kEPExtrudeSpline, t, pSplineNode, mSplineValidity);
		if (pSplineNode == NULL) mpSpline = NULL;
		else
		{
			bool del = FALSE;
			SplineShape *pSplineShape = NULL;
			ObjectState os = pSplineNode->GetObjectRef()->Eval(t);
			if (os.obj->IsSubClassOf(splineShapeClassID)) pSplineShape = (SplineShape *) os.obj;
			else {
				if (!os.obj->CanConvertToType(splineShapeClassID)) return;
				pSplineShape = (SplineShape*)os.obj->ConvertToType (t, splineShapeClassID);
				if (pSplineShape!=os.obj) del = TRUE;
			}
			BezierShape & bezShape = pSplineShape->GetShape();

			Matrix3 mSplineXfm = pSplineNode->GetObjectTM (t, &mSplineValidity);
			if (mpSpline != NULL) delete mpSpline;
			mpSpline = new Spline3D(*bezShape.GetSpline(0));

			if (del) delete pSplineShape;
		}
	}

	ivalid &= mSplineValidity;
}
bool HoudiniEngineMesh::SetInputNode(int ch, INode* node)
{
	bool result = false;
	// Input Nodes
	if (inputs.getAssetId() >= 0)
	{
		TimeValue t = GetCOREInterface()->GetTime();
		INode * selfNode = GetINode();
		Matrix3 baseTM(1);
		
		if (selfNode)
			baseTM = selfNode->GetObjectTM(t);

		bool conv_unit_i = pblock2->GetInt(pb_conv_unit_i) != 0;
		double scl = conv_unit_i ? GetRelativeScale(GetUSDefaultUnit(), 1, UNITS_METERS, 1) : 1.0;
		inputs.setNode(ch, node, t, baseTM, scl, needUpdateInputNode );
		result = true;
#if defined(USE_NOTIFYREFCHANGED)
		if (node->TestForLoop(FOREVER, this) == REF_SUCCEED) {
			ReplaceReference(1+ch, (RefTargetHandle)node);
			NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
			NotifyDependents(FOREVER, 0, REFMSG_SUBANIM_STRUCTURE_CHANGED);
		}
#endif
	}
	return result;
}
Пример #7
0
static float CalcLength(INode *bone)
{
   int n = bone->NumberOfChildren();
   float len = 0.0f;
   if (n > 0) 
   {
      Matrix3 m = bone->GetNodeTM(0);
      Point3 p = m.GetTrans();
      for (int i = 0; i<n; i++)
      {
         INode *child = bone->GetChildNode(i);
         Matrix3 cm = child->GetObjectTM(0);
         Point3 cp = cm.GetTrans();

         float clen = Length(p-cp);
         len += clen;
      }
      len /= float(n);
   }
   else
   {
      len = Length(GetLocalTM(bone).GetTrans());
   }
   return len;
}
Пример #8
0
Matrix3 plDistributor::IOTM(int iRepNode) const
{
    // objectTM = otm * nodeTM
    // objectTM * Inverse(nodeTM) = otm
    INode* repNode = fRepNodes[iRepNode];
    Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
    Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
    Matrix3 OTM = objectTM * Inverse(nodeTM);
    return OTM;
}
Пример #9
0
Matrix3 plDistributor::IInvOTM(int iRepNode) const
{
    // objectTM = otm * nodeTM
    // invOTM * objectTM = nodeTM
    // invOTM = nodeTM * invObjectTM
    INode* repNode = fRepNodes[iRepNode];
    Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0));
    Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0));
    Matrix3 invOTM = nodeTM * Inverse(objectTM);
    return invOTM;
}
Пример #10
0
MeshTopoData *TweakMouseProc::HitTest(ViewExp& vpt, IPoint2 m, int &hitVert)
{
	if ( ! vpt.IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return NULL;
	}

	int savedLimits;
	TimeValue t = GetCOREInterface()->GetTime();

	GraphicsWindow *gw = vpt.getGW();

	HitRegion hr;

	int crossing = TRUE;
	int type = HITTYPE_POINT;
	MakeHitRegion(hr,type, crossing,8,&m);
	gw->setHitRegion(&hr);
	hitVert = -1;
	MeshTopoData *hitLD = NULL;
	mHitLDIndex = -1;

	//			else gw->setRndLimits(gw->getRndLimits() & ~GW_BACKCULL);

	savedLimits = gw->getRndLimits();
	for (int ldID = 0; ldID < mod->GetMeshTopoDataCount(); ldID++)
	{
		MeshTopoData *ld = mod->GetMeshTopoData(ldID);
		INode *inode = mod->GetMeshTopoDataNode(ldID);

		Matrix3 mat = inode->GetObjectTM(t);
		gw->setTransform(mat);	
		gw->setRndLimits(((gw->getRndLimits() | GW_PICK) & ~GW_ILLUM) |  GW_BACKCULL);
		ModContext mc;

		int hindex = mod->peltData.HitTestPointToPointMode(mod,ld,vpt,gw,&m,hr,inode,&mc);
		if (hindex != -1)
		{
			hitVert = hindex;
			hitLD = ld;
			mHitLDIndex = ldID;
		}
	}

	gw->setRndLimits(savedLimits);

	return hitLD;

}
Пример #11
0
Point3 PinField::Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index) //ok
{	fValid= FOREVER;		
	if (!tmValid.InInterval(t)) 
	{	tmValid=FOREVER;
		tm=node->GetObjectTM(t,&tmValid);
		invtm=Inverse(tm);
	}
	fValid&=tmValid;
	TimeValue t1,t2;
	obj->pblock->GetValue(PB_ONTIME,t,t1,fValid);
	obj->pblock->GetValue(PB_OFFTIME,t,t2,fValid);
	Point3 OutPin;
	if ((t>=t1)&&(t<=t2))
		OutPin = Zero;
	else 
		OutPin = Zero;
	return OutPin*6.25e-03f;
}
Пример #12
0
Interval BombMod::LocalValidity(TimeValue t)
	{
	BombObject *obj = GetWSMObject(t);

   if (obj && nodeRef && !waitPostLoad && (obj->ClassID() == Class_ID(BOMB_OBJECT_CLASS_ID,0))) {
		// Force a cache of input if being edited.
		if (TestAFlag(A_MOD_BEING_EDITED))
			return NEVER;  
		Interval valid = FOREVER;
		Matrix3 tm;		
		obj->GetStrength(t,valid);
		obj->GetGravity(t,valid);
		obj->GetDetonation(t,valid);		
		tm = nodeRef->GetObjectTM(t,&valid);
		return valid;
	} else {
		return FOREVER;
		}
	}
Пример #13
0
// Clone the replicant and set its transform appropriately. Should set the plMaxNode property
// that the node's spans are collapseable? No, we'll make a separate component for that.
void plDistributor::IReplicate(Matrix3& l2w, int iRepNode, plDistribInstTab& reps, plMeshCache& mCache) const
{
    INode* repNode = fRepNodes[iRepNode];
    plDistribInstance inst;
    inst.fNode = repNode;
    inst.fNodeTM = l2w;
    inst.fObjectTM = repNode->GetObjectTM(TimeValue(0)) * Inverse(repNode->GetNodeTM(TimeValue(0))) * l2w;

    inst.fMesh = mCache.fMesh;

    inst.fFlex = mCache.fFlex;

    inst.fFade = fFade;

    inst.fBone = fBone;

    inst.fRigid = fRigid;

    reps.Append(1, &inst);
}
Пример #14
0
Point3 PinField::Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index) //ok
{	fValid= FOREVER;		
	if (!tmValid.InInterval(t)) 
	{	tmValid=FOREVER;
		tm=node->GetObjectTM(t,&tmValid);
		invtm=Inverse(tm);
	}
	fValid&=tmValid;
	TimeValue t1,t2;

	if (obj == NULL) return Point3(0.0f,0.0f,0.0f);  //667105 watje xrefs can change the base object type through proxies which will cause this to be null or the user can copy a new object type over ours

	obj->pblock->GetValue(PB_ONTIME,t,t1,fValid);
	obj->pblock->GetValue(PB_OFFTIME,t,t2,fValid);
	Point3 OutPin;
	if ((t>=t1)&&(t<=t2))
		OutPin = Zero;
	else 
		OutPin = Zero;
	return OutPin*6.25e-03f;
}
Пример #15
0
static AngAxis CalcTransform(INode *bone, NiNodeRef node, vector<NiNodeRef>& children)
{
   Matrix3 mr(TRUE);
   int n = bone->NumberOfChildren();
   if (n > 0) 
   {
      int c = 0;
      Point3 vs(0.0f, 0.0f, 0.0f), vf(0.0f, 0.0f, 0.0f);
      Matrix3 m = bone->GetNodeTM(0);
      Matrix3 m2 = TOMATRIX3(node->GetWorldTransform());
      for (int i = 0; i<n; i++)
      {
         INode *child = bone->GetChildNode(i);
         LPCTSTR name = child->GetName();
         if (HasBipedPosDOF(name))
            continue;

         Matrix3 cm = child->GetObjectTM(0);
         vs += (m.GetTrans()-cm.GetTrans());

         if (NiNodeRef child2 = FindNodeByName(children, string(child->GetName()))){
            Matrix3 cm2 = TOMATRIX3(child2->GetWorldTransform());
            vf += (m2.GetTrans()-cm2.GetTrans());
         }
         ++c;
      }
      vs = FNormalize(vs); 
      vf = FNormalize(vf);
      Point3 cross = CrossProd(vs, vf);
      if (fabs(cross.x) < 0.01 && fabs(cross.y) < 0.01 && fabs(cross.z) < 0.01)
         return AngAxis(Point3(0.0f, 0.0f, 0.0f), 0.0f);
      float dot = DotProd(vs, vf);
      return AngAxis( cross, acos( dot ) );
   }
   return mr;
}
Пример #16
0
/**
*  @brief
*    Constructor
*/
PLSceneNode::PLSceneNode(PLSceneContainer *pContainer, IGameNode *pIGameNode, const String &sName, EType nType, const String &sClassName) :
	m_pContainer(pContainer),
	m_pIGameNode(pIGameNode),
	m_sName(sName),
	m_nType(nType),
	m_sClassName(sClassName),
	m_sFlags(""),
	m_vPos(0.0f, 0.0f, 0.0f),
	m_vRot(0.0f, 0.0f, 0.0f),
	m_vScale(1.0f, 1.0f, 1.0f),
	m_nIsRotationFlipped(-1)
{
	// Check some universal flags
	INode *pMaxNode = GetMaxNode();
	if (pMaxNode) { // If this is not a container...
		TSTR sString;

		// Check whether the default PixelLight class is changed
		if (pMaxNode->GetUserPropString(_T("Class"), sString)) {
			m_sClassName = sString;

			// Erase all '"'
			int i = m_sClassName.IndexOf("\"");
			while (i >= 0) {
				m_sClassName.Delete(i, 1);
				i = m_sClassName.IndexOf("\"");
			}
		}

		// Is this 3ds Max node frozen?
		if (pMaxNode->IsFrozen())
			AddFlag("Frozen");

		// Is this 3ds Max node invisible?
		if (pMaxNode->IsHidden() || !pMaxNode->Renderable())
			AddFlag("Invisible");

		// Is this 3ds Max node excluded from lighting?
		INodeGIProperties *pINodeGIProperties = static_cast<INodeGIProperties*>(pMaxNode->GetInterface(NODEGIPROPERTIES_INTERFACE));
		if (pINodeGIProperties && pINodeGIProperties->GIGetIsExcluded())
			AddFlag("NoLighting");

		{ // Get the world space bounding box of the scene node. Because this is not 'trival' we're using
		  // the sample code from "3dsMaxSDK.chm" (3ds Max SDK) -> "The Pipeline and the INode TM Methods"
		  // to get it working correctly.
			::Object *pMaxObject = pMaxNode->GetObjectRef();
			if (pMaxObject) {
				TimeValue t = 0;
				Matrix3 mat;	// The Object TM

				// Determine if the object is in world space or object space
				// so we can get the correct TM. We can check this by getting
				// the Object TM after the world space modifiers have been
				// applied. It the matrix returned is the identity matrix the
				// points of the object have been transformed into world space.
				if (pMaxNode->GetObjTMAfterWSM(t).IsIdentity()) {
					// It's in world space, so put it back into object
					// space. We can do this by computing the inverse
					// of the matrix returned before any world space
					// modifiers were applied.
					mat = Inverse(pMaxNode->GetObjTMBeforeWSM(t));
				} else { 
					// It's in object space, get the Object TM
					mat = pMaxNode->GetObjectTM(t);
				}

				// Get the bound box, and affect it by just the scaling portion
				pMaxObject->GetDeformBBox(t, m_cBoundingBox, &mat);
			}
		}

		// We really need to flip the coordinates to OpenGL style
		m_cBoundingBox.pmin = PLTools::Convert3dsMaxVectorToOpenGLVector(m_cBoundingBox.pmin);
		m_cBoundingBox.pmax = PLTools::Convert3dsMaxVectorToOpenGLVector(m_cBoundingBox.pmax);

		// Validate minimum/maximum - I already had situations with incorrect values causing problems!
		PLTools::ValidateMinimumMaximum(m_cBoundingBox);
	}

	// Get the position, rotation and scale
	GetPosRotScale(m_vPos, m_vRot, m_vScale);
}
Пример #17
0
Point3 WindField::Force(
		TimeValue t,const Point3 &pos, const Point3 &vel,int index)
	{
	if (!obj)
		return Point3(0.0f, 0.0f, 0.0f);

	float strength, decay, turb;
	obj->pblock2->GetValue(PB_DECAY,t,decay,fValid);
	obj->pblock2->GetValue(PB_TURBULENCE,t,turb,FOREVER);
	if (decay <0.0f) decay = 0.0f;

	if (!fValid.InInterval(t) || type==FORCE_SPHERICAL || decay!=0.0f) {
		fValid = FOREVER;		
		if (!tmValid.InInterval(t)) {
			tmValid = FOREVER;
			tm = node->GetObjectTM(t,&tmValid);
			}
		fValid &= tmValid;
		obj->pblock2->GetValue(PB_STRENGTH,t,strength,fValid);
		
		if (type==FORCE_PLANAR) {
			force = Normalize(tm.GetRow(2));
			if (decay!=0.0f) {
				float dist = (float)fabs(DotProd(force,pos-tm.GetTrans()));
				strength *= (float)exp(-decay*dist);
				}			
			force *= strength * 0.0001f * forceScaleFactor;
		} else {
			float dist;
			force = pos-tm.GetTrans();
			dist  = Length(force);
			if (dist!=0.0f) force /= dist;
			if (decay!=0.0f) {				
				strength *= (float)exp(-decay*dist);
				}			
			force *= strength * 0.0001f * forceScaleFactor;
			}
		}	
	if (turb!=0.0f) {
		float freq, scale;
		Point3 tf, pt = pos-tm.GetTrans(), p;
		obj->pblock2->GetValue(PB_FREQUENCY,t,freq,FOREVER);
		obj->pblock2->GetValue(PB_SCALE,t,scale,FOREVER);
		freq *= 0.01f;
		turb *= 0.0001f * forceScaleFactor;

		p    = pt;
		p.x  = freq * float(t);
		tf.x = RTurbulence(p,scale);
		p    = pt;
		p.y  = freq * float(t);
		tf.y = RTurbulence(p,scale);
		p    = pt;
		p.z  = freq * float(t);
		tf.z = RTurbulence(p,scale);

		return force + (turb*tf);
	} else {
		return force;
		}
	}
Пример #18
0
BOOL
TrackMouseCallBack::point_on_obj(ViewExp& vpt, IPoint2 m, Point3& pt, Point3 &norm)
{
	if ( ! vpt.IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return FALSE;
	}

	// computes the normal ray at the point of intersection
	Ray ray, world_ray;
	float at, best_dist = 0.0f;
	TimeValue t = MAXScript_time();	
	Object *obj = NULL;
	Matrix3 obtm, iobtm;
	Point3 testNorm;

	BOOL found_hit = FALSE;
	
	vl->face_num_val = vl->face_bary = &undefined;
	hit_node = NULL;

	// Calculate a ray from the mouse point
	vpt.MapScreenToWorldRay(float(m.x), float(m.y), world_ray);

	for( int i=(nodeTab.Count()-1); i>=0; i-- ) {
		// Get the object from the node
		INode* node = nodeTab[i];
		ObjectState os = node->EvalWorldState(t);
		obj = os.obj;	

		// Back transform the ray into object space.
		obtm	= node->GetObjectTM(t);
		iobtm	= Inverse(obtm);
		ray.p   = iobtm * world_ray.p;
		ray.dir = VectorTransform(iobtm, world_ray.dir);
		
		// See if we hit the object
		if (obj->IsSubClassOf(triObjectClassID))
		{
			TriObject*  tobj = (TriObject*)obj;
			DWORD		fi;
			Point3		bary;
			if (tobj->mesh.IntersectRay(ray, at, testNorm, fi, bary)  &&
			   ((!found_hit) || (at<=best_dist)) )
			{
				// Calculate the hit point and transform everything back into world space.
				// record the face index and bary coord
				best_dist = at;
				pt = ray.p + ray.dir * at;
				pt = pt * obtm;
				norm = Normalize(VectorTransform(obtm, testNorm));
				vl->face_num_val = Integer::intern(fi + 1);
				vl->face_bary = new Point3Value(bary);
				hit_node = node;
				found_hit = TRUE;
			}
		}
		else if (obj->IntersectRay(t, ray, at, testNorm)  &&
				((!found_hit) || (at<=best_dist)) )
		{
			// Calculate the hit point and transform everything back into world space.
			best_dist = at;
			pt = ray.p + ray.dir * at;
			pt = pt * obtm;
			norm = Normalize(VectorTransform(obtm, testNorm));
			hit_node = node;
			found_hit = TRUE;
		}
	}
	if( found_hit ) return TRUE;

	// Failed to find a hit on any node, look at the Normal Align Vector for the first node
	if ((obj!=NULL) && obj->NormalAlignVector(t, pt, testNorm)) // See if a default NA vector is provided
	{
		pt   = pt * obtm;
		norm = Normalize(VectorTransform(obtm, testNorm));
		return TRUE;
	}
	else
		return FALSE;
}
Пример #19
0
void ParticleMesherObject::BuildMesh(TimeValue t)
   {
//check if render time
//get node
//mkae ivalid interesect with the 
   int isRendering = 0;
   ivalid = FOREVER;

   TimeValue offset;
   float foffset;
   Interval iv;
   pblock2->GetValue(particlemesher_time, 0, foffset, iv);
   foffset = -foffset;
   pblock2->GetValue(particlemesher_radius, 0, radius, iv);
   foffset *= GetTicksPerFrame();
   offset = (TimeValue) foffset;

// pblock2->GetValue(particlemesher_time, 0, foffset, iv);
   if ((lastTime == t)  )
      {
      ivalid.Set(t,t);
      return;
      }


   pblock2->GetValue(particlemesher_rendertimeonly, 0, isRendering, ivalid);
   isRendering = !isRendering;
    if ((isRendering) || (TestAFlag(A_RENDER)))
      {
      INode *node=NULL;
      pblock2->GetValue(particlemesher_pick, 0, node, ivalid);

      
      BOOL reevalGroup = FALSE;
      if ((node != NULL) && (node->IsGroupHead()) )
         {  
         for (int ch=0;ch<node->NumberOfChildren();ch++)
            {  
            INode *cnode= node->GetChildNode(ch);
            Interval iv;
            Matrix3 tm=cnode->GetObjectTM(t,&iv);
      

            if (cnode->IsGroupMember())
               {
               reevalGroup = TRUE;
               for (int groupCount = 0; groupCount < pblock2->Count(particlemesher_extranodes); groupCount++)
                  {
                  INode *extraNode = pblock2->GetINode(particlemesher_extranodes,t,ch);
                  if (cnode == extraNode)
                     {
                     reevalGroup = FALSE;
                     groupCount = pblock2->Count(particlemesher_extranodes);
                     }
                  }
               if (reevalGroup)
                  ch=node->NumberOfChildren();

               }
            }

         if (reevalGroup)
            {
            tmList.ZeroCount();
   
            pblock2->ZeroCount(particlemesher_extranodes);
            for (int ch=0;ch<node->NumberOfChildren();ch++)
               {  
               INode *cnode= node->GetChildNode(ch);
               Interval iv;
               Matrix3 tm=cnode->GetObjectTM(t,&iv);
      

               if (cnode->IsGroupMember())
                  {
                  pblock2->Append(particlemesher_extranodes,1,&cnode);
                  tmList.Append(1,&tm);
                  }
               }

            }
         }

      if (node) 
         {

         if ( (node->IsGroupHead()) && (pblock2->Count(particlemesher_extranodes)!=0))
            {

            int ct = 0;
            Matrix3 ident(1), inverseTm(1);
            mesh.setNumVerts(0);
            mesh.setNumFaces(0);
            for (int ch=0;ch<pblock2->Count(particlemesher_extranodes);ch++)
               {  
               INode *cnode = pblock2->GetINode(particlemesher_extranodes,t,ch);
               if (cnode)
                  {
                  Object *pobj = cnode->EvalWorldState(t+offset).obj;
               
                  if ( (pobj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
                      (pobj->SuperClassID() == SHAPE_CLASS_ID) )                    
                     {  


                     BOOL needDel;
                     NullView nullView;
                     Mesh *msh = ((GeomObject*)pobj)->GetRenderMesh(t+offset,cnode,nullView,needDel);

                     Mesh tmsh = *msh;

                     ivalid &= pobj->ObjectValidity(t+offset);

                     Matrix3 tm(1);
                     if (ch < tmList.Count())
                        tm = tmList[ch];
                     for (int v = 0; v < msh->numVerts; v++)
                        {
                        tmsh.verts[v] = tmsh.verts[v] * tm;
                        }
                     if (tmsh.numVerts != 0)
                        {
                        if (ct ==0)
                           {
                           mesh = tmsh;
                           }
                        else 
                           mesh = mesh + tmsh;
                  
                        ct++;
                        }

                     if (needDel) delete msh;
                     }

                     
               
                  }
                  
               }
            mesh.InvalidateTopologyCache();

            }
         else
            {
//          Object *tobj =  node->GetObjectRef();
//          macroRecorder->FunctionCall(_T("time"), 1, 0, mr_int, t);
//          macroRecorder->EmitScript();
            ObjectState os = node->EvalWorldState(t+offset);

            IParticleObjectExt* epobj;
            epobj = (IParticleObjectExt*) os.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE);
            
            if (os.obj->IsParticleSystem() && epobj)
               {
      
               if (epobj) 
                  {
                  BOOL useAllPFEvents;
                  pblock2->GetValue(particlemesher_useallpf,0,useAllPFEvents,FOREVER);
                  
                  pfNodes.ZeroCount();
                  
                  INode *basenode=NULL;
                  pblock2->GetValue(particlemesher_pick, 0, basenode, ivalid);                  

                  tmList.ZeroCount();

                  if (useAllPFEvents)
                     {
                     MyEnumProc dep;              
                     os.obj->DoEnumDependents(&dep);
                     
                     for (int i = 0; i < dep.Nodes.Count(); i++)
                        {
                        Interval valid;
                        INode *node = dep.Nodes[i];

                        Object *obj = node->GetObjectRef();

                        
                        if (ParticleGroupInterface(obj) != nullptr)
                           {
                           pfNodes.Append(1,&node);
                           Matrix3 tm = node->GetNodeTM(t+offset);
                           tmList.Append(1,&tm);
                           }
                        }                 
                     }
                  else
                     {
                     int ct = pblock2->Count(particlemesher_pfeventlist);
                     for (int i = 0; i < ct; i++)
                        {
                        INode *node;
                        pblock2->GetValue(particlemesher_pfeventlist,t,node,FOREVER,i);
                        if (node)
                           {

                           Object *obj = node->GetObjectRef();
                           if (ParticleGroupInterface(obj) != nullptr)
                              {
                              pfNodes.Append(1,&node);
                              Matrix3 tm(1);// = basenode->GetNodeTM(t+offset);
                              Matrix3 ntm = node->GetObjectTM(t+offset);
                              tm = ntm;
                              tmList.Append(1,&ntm);
                              
                              }                          
                           }
                        }
                     }
                     
                  mesh.setNumVerts(0);
                  mesh.setNumFaces(0);
                  int ct = 0;
                  for (int ch=0;ch< pfNodes.Count();ch++)
                     {  
                     INode *cnode = pfNodes[ch];
                     if (cnode)
                        {
                        Object *pobj = cnode->EvalWorldState(t+offset).obj;
                     
                        if ( (pobj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
                           (pobj->SuperClassID() == SHAPE_CLASS_ID) )                     
                           {  


                           BOOL needDel;
                           NullView nullView;
                           Mesh *msh = ((GeomObject*)pobj)->GetRenderMesh(t+offset,cnode,nullView,needDel);

                           Mesh tmsh = *msh;

                           ivalid &= pobj->ObjectValidity(t+offset);

                           Matrix3 tm(1);
                           if (ch < tmList.Count())
                              tm = tmList[ch];
                           for (int v = 0; v < msh->numVerts; v++)
                              {
                              tmsh.verts[v] = tmsh.verts[v] * tm;
                              }
                           if (tmsh.numVerts != 0)
                              {
                              if (ct ==0)
                                 {
                                 mesh = tmsh;
                                 }
                              else 
                                 {
                                 Mesh tempMesh = mesh;
                                 CombineMeshes(mesh, tempMesh, tmsh);
                                 }
                        
                              ct++;
                              }

                           if (needDel) delete msh;
                           }

                           
                     
                        }
                        
                     }
                  mesh.InvalidateTopologyCache();
                     
                     
                                       
                  }
               }
            else if ( (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID) ||
             (os.obj->SuperClassID() == SHAPE_CLASS_ID) )
               {

               BOOL needDel;
               NullView nullView;
               Mesh *msh = ((GeomObject*)os.obj)->GetRenderMesh(t+offset,node,nullView,needDel);
               ivalid &= os.obj->ObjectValidity(t);

               if (msh)
                  {
                  mesh = *msh;
                  mesh.InvalidateTopologyCache();
         
                  if (needDel) delete msh;
                  }
               }
            }
         lastTime = t;
         }
      else
         {
//build proxy mesh
         if (node == NULL)
            {
            mesh.setNumVerts(5);
            mesh.setNumFaces(8);

            mesh.setNumMaps(2);
            mesh.setNumMapVerts(0, 0);
            mesh.setNumMapVerts(1, 0);
            mesh.setNumMapFaces(0, 0);
            mesh.setNumMapFaces(1, 0);

            mesh.setVert(0, Point3(-radius,-radius, 0.0f));
            mesh.setVert(1, Point3( radius,-radius, 0.0f));
            mesh.setVert(2, Point3( radius, radius, 0.0f));
            mesh.setVert(3, Point3(-radius, radius, 0.0f));

//          mesh.setVert(4, Point3(0.0f, 0.0f, 0.0f));
            mesh.setVert(4, Point3(0.0f, 0.0f, radius));
   
            mesh.faces[0].setEdgeVisFlags(1,0,1);
            mesh.faces[0].setSmGroup(1);
            mesh.faces[0].setVerts(0,1,3);

            mesh.faces[1].setEdgeVisFlags(1,1,0);
            mesh.faces[1].setSmGroup(1);
            mesh.faces[1].setVerts(1,2,3);   

            mesh.faces[2].setEdgeVisFlags(1,1,1);
            mesh.faces[2].setSmGroup(1);
            mesh.faces[2].setVerts(0,4,1);   

            mesh.faces[3].setEdgeVisFlags(1,1,1);
            mesh.faces[3].setSmGroup(1);
            mesh.faces[3].setVerts(1,4,0);   

            mesh.faces[4].setEdgeVisFlags(1,1,1);
            mesh.faces[4].setSmGroup(1);
            mesh.faces[4].setVerts(2,4,3);   

            mesh.faces[5].setEdgeVisFlags(1,1,1);
            mesh.faces[5].setSmGroup(1);
            mesh.faces[5].setVerts(3,4,2);   

            mesh.faces[6].setEdgeVisFlags(1,0,1);
            mesh.faces[6].setSmGroup(1);
            mesh.faces[6].setVerts(3,1,0);

            mesh.faces[7].setEdgeVisFlags(1,1,0);
            mesh.faces[7].setSmGroup(1);
            mesh.faces[7].setVerts(3,2,1);   


            }

         }
      }  
   else
      {
//build proxy mesh
//build proxy mesh
      INode *node=NULL;
      pblock2->GetValue(particlemesher_pick, 0, node, ivalid);
   // if (node == NULL)
         {
            mesh.setNumVerts(5);
            mesh.setNumFaces(8);

            mesh.setNumMaps(2);
            mesh.setNumMapVerts(0, 0);
            mesh.setNumMapVerts(1, 0);
            mesh.setNumMapFaces(0, 0);
            mesh.setNumMapFaces(1, 0);

            mesh.setVert(0, Point3(-radius,-radius, 0.0f));
            mesh.setVert(1, Point3( radius,-radius, 0.0f));
            mesh.setVert(2, Point3( radius, radius, 0.0f));
            mesh.setVert(3, Point3(-radius, radius, 0.0f));

//          mesh.setVert(4, Point3(0.0f, 0.0f, 0.0f));
            mesh.setVert(4, Point3(0.0f, 0.0f, radius));
   
            mesh.faces[0].setEdgeVisFlags(1,0,1);
            mesh.faces[0].setSmGroup(1);
            mesh.faces[0].setVerts(0,1,3);

            mesh.faces[1].setEdgeVisFlags(1,1,0);
            mesh.faces[1].setSmGroup(1);
            mesh.faces[1].setVerts(1,2,3);   

            mesh.faces[2].setEdgeVisFlags(1,1,1);
            mesh.faces[2].setSmGroup(1);
            mesh.faces[2].setVerts(0,4,1);   

            mesh.faces[3].setEdgeVisFlags(1,1,1);
            mesh.faces[3].setSmGroup(1);
            mesh.faces[3].setVerts(1,4,0);   

            mesh.faces[4].setEdgeVisFlags(1,1,1);
            mesh.faces[4].setSmGroup(1);
            mesh.faces[4].setVerts(2,4,3);   

            mesh.faces[5].setEdgeVisFlags(1,1,1);
            mesh.faces[5].setSmGroup(1);
            mesh.faces[5].setVerts(3,4,2);   

            mesh.faces[6].setEdgeVisFlags(1,0,1);
            mesh.faces[6].setSmGroup(1);
            mesh.faces[6].setVerts(3,1,0);

            mesh.faces[7].setEdgeVisFlags(1,1,0);
            mesh.faces[7].setSmGroup(1);
            mesh.faces[7].setVerts(3,2,1);   

         }
      }

   mesh.InvalidateTopologyCache();
}
Пример #20
0
void BlobMesh::BuildMesh(TimeValue t)
{

	//TODO: Implement the code to build the mesh representation of the object
	//    using its parameter settings at the time passed. The plug-in should 
	//    use the data member mesh to store the built mesh.
	int numberOfNodes = pblock2->Count(pb_nodelist);

	float size, tension, renderCoarseness, viewCoarseness,coarseness;

	// Interval valid;
	pblock2->GetValue(pb_size,t,size,ivalid);
	pblock2->GetValue(pb_tension,t,tension,ivalid);
	if (tension < 0.011f) tension = 0.011f;
	if (tension > 1.0f) tension = 1.0f;

	pblock2->GetValue(pb_render,t,renderCoarseness,ivalid);
	pblock2->GetValue(pb_viewport,t,viewCoarseness,ivalid);

	BOOL autoCoarseness;
	pblock2->GetValue(pb_relativecoarseness,t,autoCoarseness,ivalid);

	BOOL largeDataSetOpt;
	pblock2->GetValue(pb_oldmetaballmethod,t,largeDataSetOpt,ivalid);


	BOOL useSoftSel;
	float minSize;
	pblock2->GetValue(pb_usesoftsel,t,useSoftSel,ivalid);
	pblock2->GetValue(pb_minsize,t,minSize,ivalid);

	if (inRender)
		coarseness = renderCoarseness;
	else coarseness = viewCoarseness;

	if (autoCoarseness)
		coarseness = size/coarseness;

	Tab<INode *> pfList;

	BOOL useAllPFEvents;
	pblock2->GetValue(pb_useallpf,0,useAllPFEvents,FOREVER);



	int pfCt = pblock2->Count(pb_pfeventlist);

	BOOL offInView;
	pblock2->GetValue(pb_offinview,0,offInView,FOREVER);



	for (int i = 0; i < pfCt; i++)
	{
		INode* node = NULL;
		pblock2->GetValue(pb_pfeventlist,0,node,FOREVER,i);
		if (node)
			pfList.Append(1,&node);
	}

	float thres = 0.6f;

	//need to get our tm
	if (selfNode == NULL)
	{
		MyEnumProc dep(true);
		DoEnumDependents(&dep);
		if (dep.Nodes.Count() > 0)
			selfNode = dep.Nodes[0];
	}

	Matrix3 baseTM(1);

	if (selfNode != NULL)
		baseTM = Inverse(selfNode->GetObjectTM(t));
	//loop throght the nodes

	if (!inRender)
	{
		if (offInView)
			numberOfNodes = 0;

	}

	std::vector<SphereData> data;
	data.reserve(500);

	for (int i = 0; i < numberOfNodes; i++)
	{
		INode* node = NULL;
		pblock2->GetValue(pb_nodelist,t,node,ivalid,i);

		if (node)
		{
			//get the nodes tm
			Matrix3 objectTM = node->GetObjectTM(t);
			Matrix3 toLocalSpace = objectTM*baseTM;

			ObjectState tos =  node->EvalWorldState(t,TRUE);

			if (tos.obj->IsParticleSystem())
			{
				SimpleParticle* pobj      = NULL;
				IParticleObjectExt* epobj = NULL;
				pobj = static_cast<SimpleParticle*>( tos.obj->GetInterface(I_SIMPLEPARTICLEOBJ) );
				if (pobj)
				{
					pobj->UpdateParticles(t, node);

					int count = pobj->parts.Count();
					data.reserve(data.size() + count);
					float closest = 999999999.9f;
					SphereData d;
					for (int pid = 0; pid < count; pid++)
					{
						TimeValue age  = pobj->ParticleAge(t,pid);
						TimeValue life = pobj->ParticleLife(t,pid);
						if (age != -1)
						{
							float psize = pobj->ParticleSize(t,pid);
							Point3 curval = pobj->parts.points[pid];
							d.center = curval * baseTM;
							d.radius = psize;
							d.oradius = psize;
							d.rsquare = psize * psize;
							d.tover4 = tension * d.rsquare *d.rsquare ;
							data.push_back(d);
						}
					}
				}
				else
				{
					epobj = (IParticleObjectExt*) tos.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE);
					if (epobj) 
					{
						
						epobj->UpdateParticles(node, t);

						int count = epobj->NumParticles();
						data.reserve(data.size() + count);
						for (int pid = 0; pid < count; pid++)
						{
							TimeValue age  = epobj->GetParticleAgeByIndex(pid);
							if (age!=-1)
							{
								INode *node = epobj->GetParticleGroup(pid);

								Point3 *curval = epobj->GetParticlePositionByIndex(pid);

								BOOL useParticle = TRUE;

								if (!useAllPFEvents)
								{
									useParticle = FALSE;
									for (int k = 0; k < pfList.Count(); k++)
									{
										if (node == pfList[k])
										{
											useParticle = TRUE;
											k = pfList.Count();
										}
									}
								}

								if ((curval) && (useParticle))
								{
									float scale = epobj->GetParticleScaleByIndex(pid) ;
									float psize = scale;

									SphereData d;
									d.center = *curval*baseTM;
									d.radius = psize;
									d.oradius = psize;
									d.rsquare = psize * psize;
									d.tover4 = tension * d.rsquare *d.rsquare ;
									data.push_back(d);
								}
							}
						}
					}

				}
			}
			else if (tos.obj->IsShapeObject()) 
			{
				PolyShape shape;

				ShapeObject *pathOb = (ShapeObject*)tos.obj;
				pathOb->MakePolyShape(t, shape);
				
				// first find out how many points there are:
				size_t num_points = 0;
				for (int i = 0; i < shape.numLines; i++)
				{
					PolyLine& line = shape.lines[i];
					num_points += line.numPts;
				}
				data.reserve(data.size() + num_points);

				for (int i = 0; i < shape.numLines; i++)
				{
					PolyLine line = shape.lines[i];
					for (int j = 0; j < line.numPts; j++)
					{
						SphereData d;
						float tsize = size;
						d.center = line.pts[j].p*toLocalSpace;
						d.radius = tsize;
						d.oradius = tsize;
						d.rsquare = tsize * tsize;
						d.tover4 = tension * d.rsquare *d.rsquare ;
						data.push_back(d);
					}
				}
			}
			else if (tos.obj->SuperClassID()==GEOMOBJECT_CLASS_ID)
			{
				SphereData d;
				BOOL converted = FALSE;

				TriObject *triObj = NULL;


				if(tos.obj->IsSubClassOf(triObjectClassID)) 
				{
					triObj = (TriObject *)tos.obj;
				}

				// If it can convert to a TriObject, do it
				else if(tos.obj->CanConvertToType(triObjectClassID)) 
				{
					triObj = (TriObject *)tos.obj->ConvertToType(t, triObjectClassID);
					converted = TRUE;
				}

				if (triObj != NULL)
				{
					Mesh* mesh = &triObj->GetMesh();
					if (mesh)
					{
						int vcount = mesh->getNumVerts();
						float *vsw = mesh->getVSelectionWeights ();
						BitArray vsel =  mesh->VertSel();
						data.reserve(data.size() + vcount);
						for (int j = 0; j < vcount; j++)
						{
							float tsize = size;
							if (useSoftSel)
							{
								tsize = 0.0f;
								if (vsw)
								{
									float v = 0.0f;
									if (vsel[j]) 
										v = 1.0f;
									else 
									{
										if (vsw)
											v = vsw[j];
									}
									if (v == 0.0f)
										tsize = 0.0f;
									else
									{
										tsize = minSize + (size -minSize)*v;
									}

								}
								else
								{
									float v = 0.0f;
									if (vsel[j]) 
										v = 1.0f;
									tsize = minSize + (size -minSize)*v;
								}
							}
							if (tsize != 0.0f)
							{
								d.center = mesh->getVert(j)*toLocalSpace;
								d.radius = tsize;
								d.oradius = tsize;
								d.rsquare = tsize * tsize;
								d.tover4 = tension * d.rsquare *d.rsquare ;
								data.push_back(d);
							}
						}
					}

					if (converted) triObj->DeleteThis();
				}
			}
			else
			{
				SphereData d;
				d.center = Point3(0.0f,0.0f,0.0f)*toLocalSpace;
				d.radius = size;
				d.oradius = size;
				d.rsquare = size * size;
				d.tover4 = tension * d.rsquare *d.rsquare ;
				data.push_back(d);
			}
		}
	}


	if ((data.size() == 0) && (numberOfNodes==0))
	{
		data.resize(1);
		data[0].center = Point3(0.0f,0.0f,0.0f);
		data[0].radius = size;
		data[0].oradius = size;
		data[0].rsquare = size * size;
		data[0].tover4 = tension * data[0].rsquare *data[0].rsquare ;

	}

	if (data.size() > 0)
	{
		int iRes = 1;
		if (!largeDataSetOpt)
		{
			MetaParticle oldBlob;
			iRes = oldBlob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness);
		}
		else
		{
			MetaParticleFast blob;
			iRes = blob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness);
		}

		// An out of memory error is the only reason iRes would be zero in either case
		if( (iRes == 0) && GetCOREInterface() )
			GetCOREInterface()->DisplayTempPrompt(GetString(IDS_NOT_ENOUGH_MEM), 5000 );
	}
	else
	{
		mesh.setNumFaces(0);
		mesh.setNumVerts(0);
	}

	mesh.InvalidateTopologyCache();

	ivalid.Set(t,t);
}
void HoudiniEngineMesh::BuildMesh(TimeValue t) 
{
	if ( buildingMesh )
		return;

	bool conv_unit_i = pblock2->GetInt(pb_conv_unit_i) != 0;
	bool conv_unit_o = pblock2->GetInt(pb_conv_unit_o) != 0;
	bool time_update = pblock2->GetInt(pb_updatetime, t) ? true : false;
	bool bypass	     = pblock2->GetInt(pb_bypass, t) ? true : false;

	if (bypass)
		reCook = true;

	hapi::Engine* engine = hapi::Engine::instance();
	buildingMesh = true;

	if (!engine || !engine->isInitialize() || bypass)
	{
		util::BuildLogoMesh(mesh);
		mesh.InvalidateTopologyCache();
		buildingMesh  = false;
		return;
	}

	bool new_loading = LoadAsset();

	if ( assetId >= 0 )
	{
		INode* selfNode = GetINode();
		Matrix3 baseTM(1);

		if (selfNode != nullptr)
			baseTM = Inverse(selfNode->GetObjectTM(t));


		float hapi_time;
		float max_time = TicksToSec(t);
		bool cook = UpdateParameters(t) | new_loading | reCook;

		HAPI_GetTime(hapi::Engine::instance()->session(), &hapi_time);


		if ( time_update && hapi_time != max_time )
		{
			HAPI_SetTime(hapi::Engine::instance()->session(), TicksToSec(t));
			cook = true;
		}
		// Cooking
		if ( cook )
		{
			hapi::Asset asset(assetId);
			if ( asset.isValid() )
			{
				try
				{
					asset.cook();
					int status;
					int wait_count = 0;
					int start_progress = 10;
					bool progressBar = false;
					do {
						Sleep(2);
						HAPI_GetStatus(hapi::Engine::instance()->session(), HAPI_STATUS_COOK_STATE, &status);

						if ( start_progress == wait_count )
						{
							StartProgress();
							progressBar = true;
						}
						if ( progressBar )
						{
							int ccount;
							int tcount;
							HAPI_GetCookingCurrentCount(hapi::Engine::instance()->session(), &ccount);
							HAPI_GetCookingTotalCount(hapi::Engine::instance()->session(), &tcount);
							int progress = (int)(((float)ccount / (float)tcount) * 100.f);
							UpdateProgress( progress );
						}
						wait_count ++;
					} while ( status > HAPI_STATE_MAX_READY_STATE );

					if ( progressBar )
					{
						EndProgress();
					}

					if ( status != HAPI_STATE_READY )
					{
						// Cooking Error
						cook = false;
					}
				}
				catch( hapi::Failure& e)
				{
					// Cooking Error
					e.lastErrorMessage();
					cook = false;
				}
			}
			else
				cook = false;
		}

		// dont need check cook flag, will check hasGeoChanged flag
		// if ( cook )
		{
			int verts = mesh.getNumVerts();
			double scl = conv_unit_o ? GetRelativeScale( UNITS_METERS, 1, GetUSDefaultUnit(), 1 ) : 1.0;
			util::BuildMeshFromCookResult( mesh, assetId, (float)scl, new_loading || (scl != outScale) || reCook );
			outScale = (float)scl;
			if (mesh.getNumVerts() && verts != mesh.getNumVerts())
			{
				mesh.InvalidateTopologyCache();
			}
		}
	}
	if ( !mesh.getNumVerts() )
	{
		util::BuildLogoMesh( mesh);
		mesh.InvalidateTopologyCache();
	}
	ivalid.Set(t,t);
	buildingMesh = false;
	reCook = false;
}
Пример #22
0
Point3 PtForceField::Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index)
{   Point3 ApplyAt,OutForce,zdir;
    fValid= FOREVER;
    if (!tmValid.InInterval(t))
    {   tmValid=FOREVER;
        tm=node->GetObjectTM(t,&tmValid);
        invtm=Inverse(tm);
    }
    ApplyAt=tm.GetTrans();
    fValid&=tmValid;
    TimeValue t1,t2;

    if (obj == NULL) return Point3(0.0f,0.0f,0.0f);  //667105 watje xrefs can change the base object type through proxies which will cause this to be null or the user can copy a new object type over ours

    obj->pblock->GetValue(PB_ONTIME,t,t1,fValid);
    obj->pblock->GetValue(PB_OFFTIME,t,t2,fValid);
    if ((t>=t1)&&(t<=t2))
    {   float BaseF;
        zdir=tm.GetRow(2);
        obj->pblock->GetValue(PB_STRENGTH,t,BaseF,fValid); //assume N
        int tpf=GetTicksPerFrame();
        //int tpf2=tpf*tpf;
        int tps=TIME_TICKSPERSEC;
        int tps2=tps*tps;
        //int FToTick=(int)((float)tps/(float)GetFrameRate());
        BaseF/=(float)tps2;//convert to kg-m/t2
        BaseF*=100.0f; //convert to kg-cm/t2
        int UnitsVal;
        obj->pblock->GetValue(PB_UNITS,t,UnitsVal,fValid);
        if (UnitsVal!=0) BaseF*=4.4591f; //lbf is this much larger than N=kg-m/s2
        TimeValue tage=t-t1;
        TimeValue Per1,Per2;
        obj->pblock->GetValue(PB_TIMEPER1,t,Per1,fValid);
        obj->pblock->GetValue(PB_TIMEPER2,t,Per2,fValid);
        float scalefactor=1.0f;
        int sintoggle;
        obj->pblock->GetValue(PB_ENABLESINES,t,sintoggle,fValid);
        if (sintoggle)
        {   if (Per1>0)
            {   float phase1,amp1;
                float relage1=(float)tage/(float)Per1;
                obj->pblock->GetValue(PB_PHASPER1,t,phase1,fValid);
                obj->pblock->GetValue(PB_AMP1,t,amp1,fValid);
                scalefactor+=0.01f*amp1*(float)sin(TWOPI*relage1+phase1);
            }
            if (Per2>0)
            {   float phase2,amp2;
                float relage2=(float)tage/(float)Per2;
                obj->pblock->GetValue(PB_PHASPER2,t,phase2,fValid);
                obj->pblock->GetValue(PB_AMP2,t,amp2,fValid);
                scalefactor+=0.01f*amp2*(float)sin(TWOPI*relage2+phase2);
            }
        }
        int feedback;
        obj->pblock->GetValue(PB_FEEDBACKON,t,feedback,fValid);
        float scalefactorg=1.0f;
        if (feedback)
        {   float targetspeed,loopgain;
            obj->pblock->GetValue(PB_TARGETVEL,t,targetspeed,fValid);
            targetspeed/=(float)tpf;
            obj->pblock->GetValue(PB_CONTROLGAIN,t,loopgain,fValid);
            float diffspeed=targetspeed-DotProd(vel,zdir);
            //scalefactorg*=diffspeed*loopgain/(float)tpf;
            scalefactorg*=diffspeed*loopgain/100.0f;
            int revon;
            obj->pblock->GetValue(PB_REVERSIBLE,t,revon,fValid);
            if ((!revon)&&(scalefactorg<0.0f)) scalefactorg=0.0f;
        }
        OutForce=zdir*BaseF*scalefactor*scalefactorg;
        int rangeon;
        obj->pblock->GetValue(PB_RANGEON,t,rangeon,fValid);
        if (rangeon)
        {   float maxrange;
            obj->pblock->GetValue(PB_RANGEVAL,t,maxrange,fValid);
            float distance=Length(ApplyAt-pos);
            if (distance<maxrange)
            {   if (maxrange>FLOAT_EPSILON) OutForce*=(1.0f-distance/maxrange);
                else OutForce=Zero;
            }
            else OutForce=Zero;
        }
    }
    else OutForce=Zero;
    return OutForce*6.25e-03f;
}
Пример #23
0
void BombMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
	{	
	BombObject *bobj = GetWSMObject(t);

   if (bobj && nodeRef && (bobj->ClassID() == Class_ID(BOMB_OBJECT_CLASS_ID,0))) {
		assert(os->obj->IsSubClassOf(triObjectClassID));
		TriObject *triOb = (TriObject *)os->obj;
		Interval valid = FOREVER;

		if (os->GetTM()) {
			Matrix3 tm = *(os->GetTM());
			for (int i=0; i<triOb->GetMesh().getNumVerts(); i++) {
				triOb->GetMesh().verts[i] = triOb->GetMesh().verts[i] * tm;
				}			
			os->obj->UpdateValidity(GEOM_CHAN_NUM,os->tmValid());
			os->SetTM(NULL,FOREVER);
			}
		
		if (waitPostLoad) {
			valid.SetInstant(t);
			triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
			triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
			return;
			}		

		Matrix3 tm;		
		TimeValue det  = bobj->GetDetonation(t,valid);	
		float strength = bobj->GetStrength(t,valid) * STRENGTH_CONSTANT;
		float grav     = bobj->GetGravity(t,valid);		
		float chaos    = bobj->GetChaos(t,valid);
		float chaosBase = (float(1)-chaos/2);
		float rotSpeed = bobj->GetSpin(t,valid) * TWOPI/float(TIME_TICKSPERSEC);
		int minClust = bobj->GetMinFrag(t,valid), maxClust = bobj->GetMaxFrag(t,valid);
		if (minClust<1) minClust = 1;
		if (maxClust<1) maxClust = 1;
		int clustVar = maxClust-minClust+1;
		float falloff = bobj->GetFalloff(t,valid);
		int useFalloff = bobj->GetFalloffOn(t,valid);
		int seed = bobj->GetSeed(t,valid);		

		//tm = nodeRef->GetNodeTM(t,&valid);		
		tm = nodeRef->GetObjectTM(t,&valid);
		
		if (t<det) {
			valid.Set(TIME_NegInfinity,det-1);
			triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
			triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
			triOb->PointsWereChanged();		
			return;		
			}

		float dt = float(t-det);
		valid.SetInstant(t);

		int n0=0,n1=1,n2=2,nv;
		Point3 v, p0, p1, g(0.0f,0.0f,grav*GRAVITY_CONSTANT);
		Tab<Point3> l_newVerts ; 

		Face *f = triOb->GetMesh().faces;
		float dot;		

		Mesh &mesh = triOb->GetMesh();

		// First, segment the faces.
		srand((unsigned int)seed);		
		Tab<DWORD> vclust;
		Tab<DWORD> vmap;
		Tab<Point3> nverts;
		vclust.SetCount(mesh.getNumVerts());
		vmap.SetCount(mesh.getNumVerts());		
		int numClust = 0;

		if (minClust==1 && maxClust==1) {
			// Simple case... 1 face per cluster
			nv = triOb->GetMesh().getNumFaces() * 3;
			l_newVerts.SetCount(nv);
			vclust.SetCount(nv);
			for (int i=0; i<nv; i++) {
				vclust[i] = i/3;
				}
         for (int i=0,j=0; i<mesh.getNumFaces(); i++) {
				l_newVerts[j]   = mesh.verts[mesh.faces[i].v[0]];
				l_newVerts[j+1] = mesh.verts[mesh.faces[i].v[1]];
				l_newVerts[j+2] = mesh.verts[mesh.faces[i].v[2]];
				mesh.faces[i].v[0] = j;
				mesh.faces[i].v[1] = j+1;
				mesh.faces[i].v[2] = j+2;
				j += 3;
				}
			numClust = triOb->GetMesh().getNumFaces();
		} else {
			// More complex case... clusters are randomely sized
			for (int i=0; i<mesh.getNumVerts(); i++) {
				vclust[i] = UNDEFINED;
				vmap[i] = i;
				}
			int cnum = 0;
         for (int i=0; i<mesh.getNumFaces(); ) {
				int csize = int(Rand1()*float(clustVar)+float(minClust));
				if (i+csize>mesh.getNumFaces()) {
					csize = mesh.getNumFaces()-i;					
					}
				
				// Make sure each face in the cluster has at least 2 verts in common with another face.
				BOOL verified = FALSE;
				while (!verified) {
					verified = TRUE;
					if (csize<2) break;

					for (int j=0; j<csize; j++) {
						BOOL match = FALSE;
						for (int k=0; k<csize; k++) {
							if (k==j) continue;
							int common = 0;
							for (int i1=0; i1<3; i1++) {
								for (int i2=0; i2<3; i2++) {
									if (mesh.faces[i+j].v[i1]==
										mesh.faces[i+k].v[i2]) common++;
									}
								}
							if (common>=2) {
								match = TRUE;
								break;
								}
							}
						if (!match) {
							csize = j;
							verified = FALSE; // Have to check again
							break;
							}
						}
					}
				if (csize==0) csize = 1;

				// Clear the vert map
				for (int j=0; j<mesh.getNumVerts(); j++) vmap[j] = UNDEFINED;			

				// Go through the cluster and remap verts.
            for (int j=0;j<csize; j++) {
					for (int k=0; k<3; k++) {
						if (vclust[mesh.faces[i+j].v[k]]==UNDEFINED) {
							vclust[mesh.faces[i+j].v[k]] = cnum;
						} else
						if (vclust[mesh.faces[i+j].v[k]]!=(DWORD)cnum) {
							if (vmap[mesh.faces[i+j].v[k]]==UNDEFINED) {
								vclust.Append(1,(DWORD*)&cnum,50);
								nverts.Append(1,&mesh.verts[mesh.faces[i+j].v[k]],50);
								mesh.faces[i+j].v[k] =
									vmap[mesh.faces[i+j].v[k]] = 
										mesh.getNumVerts()+nverts.Count()-1;
							} else {
								mesh.faces[i+j].v[k] =
									vmap[mesh.faces[i+j].v[k]];
								}
							}
						}
					}
				
				cnum++;
				numClust++;
				i += csize;
				}

			nv = mesh.getNumVerts() + nverts.Count();
			l_newVerts.SetCount(nv);

         int i;
			for (i=0; i<mesh.getNumVerts(); i++) 
				l_newVerts[i] = mesh.verts[i];
			for (   ; i<mesh.getNumVerts()+nverts.Count(); i++) 
				l_newVerts[i] = nverts[i-mesh.getNumVerts()];

		}

		// Find the center of all clusters
		Tab<Point3> clustCent;
		Tab<DWORD> clustCounts;
		clustCent.SetCount(numClust);
		clustCounts.SetCount(numClust);
		for (int i=0; i<numClust; i++) {
			clustCent[i]   = Point3(0,0,0);
			clustCounts[i] = 0;
			}
      for (int i=0; i<nv; i++) {
			if (vclust[i]==UNDEFINED) continue;
			clustCent[vclust[i]] += l_newVerts[i];
			clustCounts[vclust[i]]++;
			}

		// Build transformations for all clusters
		Tab<Matrix3> mats;
		mats.SetCount(numClust);
		srand((unsigned int)seed);
      for (int i=0; i<numClust; i++) {
			if (clustCounts[i]) clustCent[i] /= float(clustCounts[i]);

			v   = clustCent[i] - tm.GetTrans();
			float u = 1.0f;
			if (useFalloff) {
				u = 1.0f - Length(v)/falloff;
				if (u<0.0f) u = 0.0f;
				}
			dot = DotProd(v,v);
			if (dot==0.0f) dot = 0.000001f;
			v  = v / dot * strength * u;
			v.x *= chaosBase + chaos * Rand1();
			v.y *= chaosBase + chaos * Rand1();
			v.z *= chaosBase + chaos * Rand1();
			p1 = v*dt + 0.5f*g*dt*dt; // projectile motion

			// Set rotation
			Point3 axis;
			axis.x = -1.0f + 2.0f*Rand1();
			axis.y = -1.0f + 2.0f*Rand1();
			axis.z = -1.0f + 2.0f*Rand1();
			axis = Normalize(axis);
			float angle = dt*rotSpeed*(chaosBase + chaos * Rand1())*u;
			Quat q = QFromAngAxis(angle, axis);
			q.MakeMatrix(mats[i]);
			
			mats[i].PreTranslate(-clustCent[i]);
			mats[i].Translate(clustCent[i]+p1);			
			}

		// Now transform the clusters
      for (int i=0; i<nv; i++) {
			if (vclust[i]==UNDEFINED) continue;
			l_newVerts[i] = l_newVerts[i] * mats[vclust[i]];
			}
			
		triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
		triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
		triOb->PointsWereChanged();		

		triOb->GetMesh().setNumVerts(nv,FALSE,TRUE);

		//assign the new vertices to the mesh
      for ( int i=0; i < nv; i++)
			triOb->GetMesh().setVert( i,l_newVerts[i]);
		}		 
	}
Пример #24
0
void SWrapMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{	SWrapObject *obj = (SWrapObject *)GetWSMObject(t);
	INode *pnode;
	TriObject *towrapOb=NULL;Object *pobj=NULL;
	if (obj) pnode=obj->custnode;
	if (obj && nodeRef && pnode) 
	{	Interval valid = FOREVER;
		if (!obj->cmValid.InInterval(t))
		{   pobj = pnode->EvalWorldState(t).obj;
			obj->cmValid=pobj->ObjectValidity(t);
			Matrix3 tm=pnode->GetObjectTM(t,&(obj->cmValid));
			TriObject *wrapOb=IsUseable(pobj,t);
			if (wrapOb)
			{ if (obj->cmesh) delete obj->cmesh; 
			  obj->cmesh=new Mesh;
			   obj->cmesh->DeepCopy(&wrapOb->GetMesh(),
			     PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|PART_TOPO|TM_CHANNEL);
			   for (int ic=0;ic<obj->cmesh->getNumVerts();ic++)
			     obj->cmesh->verts[ic]=obj->cmesh->verts[ic]*tm;
			  GetVFLst(obj->cmesh,&obj->vnorms,&obj->fnorms);
			  if (wrapOb!=pobj) wrapOb->DeleteThis();
			}
 		}
		if (!obj->cmesh) return;
		if ((obj->cmesh->getNumVerts()==0)||(obj->cmesh->getNumFaces()==0)) 
			return;		 
//		Matrix3 invtm=Inverse(obj->tm);
		valid=obj->cmValid;
		Matrix3 ctm;
		ctm = nodeRef->GetNodeTM(t,&valid);
		Ray ray;
		Point3 v=-ctm.GetRow(2);
//		Matrix3 nooff=invtm;nooff.NoTrans();
		ray.dir=v;//*nooff;
		int selverts;
		float kdef,standoff;
		obj->pblock->GetValue(PB_USESELVERTS,t,selverts,valid);
		obj->pblock->GetValue(PB_KIDEFAULT,t,kdef,valid);
		obj->pblock->GetValue(PB_STANDOFF,t,standoff,valid);
		BezierShape stowrapOb;
		int found=0;
		Matrix3 towtm(1);
		if (os->GetTM()) 
			towtm=*(os->GetTM());
		Matrix3 invtowtm=Inverse(towtm);
		Point3 vert;
		Class_ID cid=os->obj->ClassID(),es=EDITABLE_SURF_CLASS_ID,efp=FITPOINT_PLANE_CLASS_ID,ecv=EDITABLE_CVCURVE_CLASS_ID,ecfp=EDITABLE_FPCURVE_CLASS_ID;
		if (((cid==EDITABLE_SURF_CLASS_ID)||(cid==FITPOINT_PLANE_CLASS_ID))||((cid==EDITABLE_CVCURVE_CLASS_ID)||(cid==EDITABLE_FPCURVE_CLASS_ID)))
		{ Object* nurbobj=os->obj;
		  int num=nurbobj->NumPoints();
		  for (int i=0;i<num;i++)
		  {	vert=DoIntersect(nurbobj->GetPoint(i)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
		    nurbobj->SetPoint(i,(vert*invtowtm));
		  }
		}
#ifndef NO_PATCHES
		else if (os->obj->IsSubClassOf(patchObjectClassID))
		{ PatchObject* patchob=(PatchObject *)os->obj;
		  PatchMesh *pm=&(patchob->patch);
		  int nv=pm->getNumVerts();
		  BitArray sel = pm->VertSel();
		  for (int i=0;i<nv;i++)
		  { if (!selverts||sel[i])
			{ vert=DoIntersect(pm->getVert(i).p*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
		      vert=vert*invtowtm;
		      pm->setVert(i,vert);
			}
		  }
/*		  pm->buildLinkages();
		  pm->computeInteriors();
		  pm->InvalidateGeomCache();*/
		}
#endif // NO_PATCHES
		else if (towrapOb=IsUseable(os->obj,t))
		{	Point3 tvector;
			float dist;
			float *vssel = NULL;
		  if (selverts) 
			  vssel = towrapOb->GetMesh().getVSelectionWeights();
		  for (int i=0;i<towrapOb->GetMesh().getNumVerts();i++)
		  { 
				if ((!selverts)||(towrapOb->GetMesh().vertSel[i])
							   ||(vssel&&vssel[i]))
				{
					vert = DoIntersect(towrapOb->GetMesh().verts[i]*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
					vert = vert*invtowtm;
					if (vssel&&vssel[i])
					{
						tvector = vert - towrapOb->GetMesh().verts[i];
						dist = Length(tvector);
						if ((float)fabs(dist) > EPSILON)
							tvector = tvector/dist;
						else
							tvector = Zero;
						vert = towrapOb->GetMesh().verts[i] + dist*vssel[i]*tvector;
					}
					towrapOb->GetMesh().verts[i] = vert;
				}
		  }
		  if (towrapOb!=os->obj) 
			  towrapOb->DeleteThis();
		}
		else if((os->obj->IsSubClassOf(splineShapeClassID))||(os->obj->CanConvertToType(splineShapeClassID))) 
		{ SplineShape *attSplShape = (SplineShape *)os->obj->ConvertToType(t,splineShapeClassID);
		if (attSplShape) 
		{ stowrapOb=attSplShape->shape;
		  for (int poly=0; poly<stowrapOb.splineCount; ++poly)
		  { Spline3D *spline = stowrapOb.GetSpline(poly);
			int verts = spline->Verts();
			int knots = spline->KnotCount();
			BitArray sel = stowrapOb.VertexTempSel(poly);
			Point3 cknot,cknot2;
			{ for(int k=0; k<knots; ++k) 
			  {	int vert = k * 3 + 1;
				if (!selverts||sel[vert])  
				{ cknot=DoIntersect(spline->GetKnotPoint(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
				  attSplShape->shape.SetVert(poly,vert,cknot*invtowtm);
				  if (found)
				  { int knotType = spline->GetKnotType(k);
				    if(knotType & KTYPE_BEZIER) 
				    { cknot2= DoIntersect(spline->GetInVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
					attSplShape->shape.SetVert(poly,vert-1,(found?cknot2:cknot)*invtowtm);
				  	  cknot2= DoIntersect(spline->GetOutVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
					  attSplShape->shape.SetVert(poly,vert+1,(found?cknot2:cknot)*invtowtm);
					}
				  }
				}
			  }
			}
		  }
		  if (attSplShape!=os->obj) attSplShape->DeleteThis();
		}
	  }
//	os->obj->PointsWereChanged();
	os->obj->UpdateValidity(GEOM_CHAN_NUM,valid);	
//	NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

  }
}