Ejemplo n.º 1
0
// go through every (child) object
static Bool Recurse(HierarchyHelp *hh, BaseThread *bt, BaseObject *main, BaseObject *op, const Matrix &ml, Real srad, Real crad, LONG sub, Bool single)
{
	// test if input object if polygonal
	if (op->GetType()==Opolygon)
	{
		BaseObject *tp   = NULL;
		PolyInfo	 *pli  = NULL;
		const Vector *padr = ToPoly(op)->GetPointR();
		Vector pa,pb;
		LONG       pcnt  = ToPoly(op)->GetPointCount(),i,side,a=0,b=0;
		const CPolygon *vadr = ToPoly(op)->GetPolygonR();
		LONG       vcnt  = ToPoly(op)->GetPolygonCount();
		Matrix     m;
		Neighbor	 n;

		// load names from resource
		String		 pstr = GeLoadString(IDS_ATOM_POINT);
		String		 estr = GeLoadString(IDS_ATOM_EDGE);

		// initialize neighbor class
		if (!n.Init(pcnt,vadr,vcnt,NULL)) return FALSE;

		// create separate objects
		// if this option is enabled no polygonal geometry is build - more parametric objects
		// are returned instead
		if (single)
		{
			for (i=0; i<pcnt; i++)
			{
				// alloc sphere primitive
				tp=BaseObject::Alloc(Osphere);
				if (!tp) return FALSE;

				// add phong tag
				if (!tp->MakeTag(Tphong)) return FALSE;
				tp->SetName(pstr+" "+LongToString(i));

				// set object parameters
				BaseContainer *bc = tp->GetDataInstance();
				bc->SetReal(PRIM_SPHERE_RAD,srad);
				bc->SetReal(PRIM_SPHERE_SUB,sub);

				// insert as last object under main
				tp->InsertUnderLast(main);

				// set position in local coordinates
				tp->SetRelPos(padr[i]*ml);
			}

			for (i=0; i<vcnt; i++)
			{
				// get polygon info for i-th polygon
				pli = n.GetPolyInfo(i);

				for (side=0; side<4; side++)
				{
					// only proceed if edge has not already been processed
					// and edge really exists (for triangles side 2 from c..d does not exist as c==d)
					if (pli->mark[side] || side==2 && vadr[i].c==vadr[i].d) continue;

					// alloc cylinder primitive
					tp=BaseObject::Alloc(Ocylinder);
					if (!tp) return FALSE;

					// add phong tag
					if (!tp->MakeTag(Tphong)) return FALSE;

					switch (side)
					{
						case 0: a=vadr[i].a; b=vadr[i].b; break;
						case 1: a=vadr[i].b; b=vadr[i].c; break;
						case 2: a=vadr[i].c; b=vadr[i].d; break;
						case 3: a=vadr[i].d; b=vadr[i].a; break;
					}

					tp->SetName(estr+" "+LongToString(pli->edge[side]));

					pa = padr[a]*ml;
					pb = padr[b]*ml;

					// set object parameters
					BaseContainer *bc = tp->GetDataInstance();
					bc->SetReal(PRIM_CYLINDER_RADIUS,crad);
					bc->SetReal(PRIM_CYLINDER_HEIGHT,Len(pb-pa));
					bc->SetReal(PRIM_AXIS,4);
					bc->SetLong(PRIM_CYLINDER_CAPS,FALSE);
					bc->SetLong(PRIM_CYLINDER_HSUB,1);
					bc->SetLong(PRIM_CYLINDER_SEG,sub);

					// place cylinder at edge center
					tp->SetRelPos((pa+pb)*0.5);

					// build edge matrix
					m.v3=!(pb-pa);
					RectangularSystem(m.v3,&m.v1,&m.v2);
					tp->SetRelRot(MatrixToHPB(m, tp->GetRotationOrder()));

					// insert as last object under main
					tp->InsertUnderLast(main);
				}
			}
		}
		else
		{
			// check if polygonal geometry has to be built
			tp = BuildPolyHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt);

			if (tp)
			{
				tp->SetName(op->GetName());
				tp->InsertUnderLast(main);

				// check if isoparm geometry has to be built
				if (hh->GetBuildFlags()&BUILDFLAGS_ISOPARM)
				{
					LineObject *ip = BuildIsoHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt);

					// isoparm always needs to be set into a polygon object
					if (ip) tp->SetIsoparm(ip);
				}
			}
		}
	}

	for (op=op->GetDown(); op; op=op->GetNext())
		if (!Recurse(hh,bt,main,op,ml*op->GetMl(),srad,crad,sub,single)) return FALSE;

	// check for user break
	return !bt || !bt->TestBreak();
}
Ejemplo n.º 2
0
void DropEffector::ModifyPoints(BaseObject* op, BaseObject* gen, BaseDocument* doc, EffectorDataStruct* data, MoData* md, BaseThread* thread)
{
	if (!ed.target || !rcol || data->strength == 0.0)
		return;

	C4D_Falloff* falloff = GetFalloff();
	if (!falloff)
		return;

	Int32	 i = 0;
	Float	 fall	 = 0.0;
	Vector off	 = Vector(0.0);
	Vector ray_p = Vector(0.0), ray_dir = Vector(0.0);
	Vector targ_off = Vector(0.0), targ_hpb = Vector(0.0);

	MDArray<Int32>	flag_array = md->GetLongArray(MODATA_FLAGS);
	MDArray<Matrix> mat_array	 = md->GetMatrixArray(MODATA_MATRIX);
	MDArray<Float>	weight_array = md->GetRealArray(MODATA_WEIGHT);

	if (!mat_array)
		return;

	Int32 mdcount = (Int32)md->GetCount();
	for (i = 0; i < mdcount; i++)
	{
		//If the particle isn't visible, don't calculate
		if (!(flag_array[i] & MOGENFLAG_CLONE_ON) || (flag_array[i] & MOGENFLAG_DISABLE))
			continue;

		//Multiply into global space
		off = mat_array[i].off;
		off = ed.genmg * off;

		//Sample the falloff
		falloff->Sample(off, &fall, true, weight_array[i]);
		if (fall == 0.0)
			continue;

		//Set up the ray for the collision
		ray_p = ed.itargmg * off;
		switch (ed.mode)
		{
			default:
			case DROPEFFECTOR_MODE_PNORMAL:		ray_dir = ed.genmg.TransformVector(mat_array[i].v3); break;
			case DROPEFFECTOR_MODE_NNORMAL:		ray_dir = ed.genmg.TransformVector(-mat_array[i].v3); break;
			case DROPEFFECTOR_MODE_AXIS:			ray_dir = (ed.targmg.off - off); break;
			case DROPEFFECTOR_MODE_SELFAXIS:	ray_dir = (ed.genmg.off - off);	break;
			case DROPEFFECTOR_MODE_PX:				ray_dir = Vector(1.0, 0.0, 0.0); break;
			case DROPEFFECTOR_MODE_PY:				ray_dir = Vector(0.0, 1.0, 0.0); break;
			case DROPEFFECTOR_MODE_PZ:				ray_dir = Vector(0.0, 0.0, 1.0); break;
			case DROPEFFECTOR_MODE_NX:				ray_dir = Vector(-1.0, 0.0, 0.0);	break;
			case DROPEFFECTOR_MODE_NY:				ray_dir = Vector(0.0, -1.0, 0.0);	break;
			case DROPEFFECTOR_MODE_NZ:				ray_dir = Vector(0.0, 0.0, -1.0);	break;
		}
		ray_dir = ed.itargmg.TransformVector(ray_dir);

		//Calculate an intersection
		if (rcol->Intersect(ray_p, !ray_dir, ed.maxdist, false))
		{
			if (rcol->GetNearestIntersection(&rcolres))
			{
				fall *= data->strength;

				targ_off = Blend(mat_array[i].off, ed.igenmg * (ed.targmg * rcolres.hitpos), fall);
				targ_hpb = VectorToHPB(ed.igenmg.TransformVector(ed.targmg.TransformVector(rcolres.s_normal)));

				mat_array[i] = HPBToMatrix(Blend(MatrixToHPB(mat_array[i], ROTATIONORDER_DEFAULT), targ_hpb, fall), ROTATIONORDER_DEFAULT);
				mat_array[i].off = targ_off;
			}
		}
	}
}