Example #1
0
void prop(std::vector<double> &pos, std::vector<double> &vel, double dt, int i){
	// Updating Distance Between Bodies
	double r = mag(VecSub(pos, bodies[i].getPos()));
	
	// Updating Net Force
	std::vector<double> fNet = VecScaleMulti((VecSub(pos, bodies[i].getPos())), (G*bodies[0].getMass()*bodies[1].getMass())/(r*r*r)); // Update Netforce
			
	// Updating Pmomentum
	vel = VecAdd(vel, VecScaleMulti(fNet, dt/bodies[(i+1)%2].getMass()));
	
	// Updating Pos
	pos=VecAdd(pos, VecScaleMulti(vel, dt));
}
Example #2
0
void FractalProjector::
new_vertex(Vertex* vrt, Face* parent)
{
//	set the vertex to the center by calling the parents method
	RefinementCallbackLinear<APosition>::new_vertex(vrt, parent);

//	calculate the normal of the face
	vector3 n;
	CalculateNormal(n, parent, m_aaPos);

//	we have to alter the length.
//	first scale it to the average length of the faces edges,
//	then scale it with the given scaleFac.
	number avLen = 0;

	size_t numVrts = parent->num_vertices();
	for(size_t i = 0; i < numVrts; ++i){
		avLen += VecDistance(m_aaPos[parent->vertex(i)],
							 m_aaPos[parent->vertex((i+1)% numVrts)]);
	}
	avLen /= (number)numVrts;
	VecScale (n, n, m_scaleFac * avLen);

//	offset the vertex by the calculated normal
	VecAdd(m_aaPos[vrt], m_aaPos[vrt], n);
}
Example #3
0
/*************
 * DESCRIPTION:   Adjust the initial ray to account for an aperture and a focal
 *       distance.  The ray argument is assumed to be an initial ray, and
 *       always reset to the eye point.  It is assumed to be unit length.
 * INPUT:         ray      pointer to ray structure
 *                world    pointer to world structure
 * OUTPUT:        none
 *************/
void CAMERA::FocusBlurRay(RAY *ray, WORLD *world)
{
	VECTOR circle_point, aperture_inc;

	/*
	 * Find a point on a unit circle and scale by aperture size.
	 * This simulates rays passing thru different parts of the aperture.
	 * Treat the point as a vector and rotate it so the circle lies
	 * in the plane of the screen. Add the aperture increment to the
	 * starting position of the ray. Stretch the ray to be focaldist
	 * in length. Subtract the aperture increment from the end of the
	 * long ray. This insures that the ray heads toward a point at
	 * the specified focus distance, so that point will be in focus.
	 * Normalize the ray, and that's it. Really.
	 */

	world->UnitCirclePoint(&circle_point, ray->sample);
	VecComb(aperture * circle_point.x, &scrni,
			  aperture * circle_point.y, &scrnj,
			  &aperture_inc);
	VecAdd(&aperture_inc, &pos, &(ray->start));
	VecScale(focaldist, &ray->dir, &(ray->dir));
	VecSub(&ray->dir, &aperture_inc, &(ray->dir));
	VecNormalizeNoRet(&ray->dir);
}
Example #4
0
/*************
 * DESCRIPTION:   sets the new object specs
 * INPUT:         disp     pointer to display structure
 *                pos      translate factor
 *                ox,oy,oz rotate factor
 *                size     scale factor
 * OUTPUT:        none
 *************/
void CAMERA::SetObject(DISPLAY *disp, VECTOR *pos, VECTOR *ox, VECTOR *oy, VECTOR *oz, VECTOR *size)
{
	MATRIX m;

	if(disp)
	{
		if(disp->view->viewmode == VIEW_CAMERA)
		{
			VecAdd(pos,&this->pos,&disp->view->pos);

			if(!track)
			{
				InvOrient(ox, oy, oz, &disp->view->axis_x, &disp->view->axis_y, &disp->view->axis_z);
				m.SetOMatrix(&orient_x,&orient_y,&orient_z);
				m.MultVectMat(&disp->view->axis_x);
				m.MultVectMat(&disp->view->axis_y);
				m.MultVectMat(&disp->view->axis_z);
			}
			else
			{
				UpdateTracking(&disp->view->pos);
				InvOrient(&orient_x, &orient_y, &orient_z, &disp->view->axis_x, &disp->view->axis_y, &disp->view->axis_z);
			}
		}
	}
	SetVector(&bboxmin, -this->size.z*.5f, -this->size.z*.5f, -this->size.z);
	SetVector(&bboxmax, this->size.z*.5f, this->size.z*1.3f, this->size.z*1.5f);
}
Example #5
0
int main(int argc, char** argv)
{	
	int i;
 	int sz = atoi(argv[1]);
 	int element = atoi(argv[2]);
 	srand( (unsigned)time( NULL ));

	IntVectorPtr vector = VecNew(initialCapacity);

	for(i=0;i<sz+1;i++)
		vector = VecAdd(vector,rand()%100);

	printlist(vector, sz);

	if (argc == 3)
	{	
		VecQuickSort(vector);
		printf("\nThe position of the number %d is %d\n", element, VecBinarySearch(vector, element));
	} else if ( strcmp(argv[3], "-l") == 0 )
	{
		VecQuickSort2(vector, 1, sz-1);
		printf("\nThe position of the number %d is %d\n", element, VecBinarySearch2(vector->data, 0, sz, element));	
	}
		
		
	printlist(vector, sz);

	VecDelete(vector);
	return 0;
}
Example #6
0
////////////////////////////////////////////////////////////////////////
//	CalculateVertexNormals
bool CalculateVertexNormals(Grid& grid,
                            Grid::AttachmentAccessor<Vertex, APosition>& aaPos,
                            Grid::AttachmentAccessor<Vertex, ANormal>& aaNorm)
{
//	set all normals to zero
    {
        for(VertexIterator iter = grid.begin<Vertex>();
                iter != grid.end<Vertex>(); iter++)
            aaNorm[*iter] = vector3(0, 0, 0);
    }
//	loop through all the faces, calculate their normal and add them to their connected points
    {
        for(FaceIterator iter = grid.begin<Face>(); iter != grid.end<Face>(); iter++)
        {
            Face* f = *iter;
            vector3 vN;

            CalculateNormal(vN, f, aaPos);

            for(size_t i = 0; i < f->num_vertices(); ++i)
                VecAdd(aaNorm[f->vertex(i)], aaNorm[f->vertex(i)], vN);
        }
    }
//	loop through all the points and normalize their normals
    {
        for(VertexIterator iter = grid.begin<Vertex>();
                iter != grid.end<Vertex>(); iter++)
            VecNormalize(aaNorm[*iter], aaNorm[*iter]);
    }
//	done
    return true;
}
Example #7
0
//给定两个R矩阵,和测得的l1,l2,(l1,l2均为3*1向量即[0;0;l1])求末端轨迹P
void SolveP(const float* R1, const float* R2, const float* l1, const float* l2, float *P)
{
    float M1[3];
    float M2[3];
    MatMultVec(R1, l1, M1);
    MatMultVec(R2, l2, M2);
    VecAdd(M1,M2,P);
}
Example #8
0
/*************
 * DESCRIPTION:   transfer camera data to RayStorm Interface
 * INPUT:         stack    matrix stack
 *                object   pointer to created rsi object
 * OUTPUT:        rsiERR_NONE if ok else error number
 *************/
rsiResult CAMERA::ToRSI(rsiCONTEXT *rc, MATRIX_STACK *stack, void **object)
{
	VECTOR up, look, orient_x, orient_y, orient_z, pos;
	MATRIX m, m1;
	int rsiflags;
	rsiResult err;

	stack->GenerateAxis(&orient_x, &orient_y, &orient_z, &pos);

	m.SetOMatrix(&orient_x, &orient_y, &orient_z);
	if(track)
	{
		track->GetObjectMatrix(&m1);
		m1.GenerateAxis(&orient_x, &orient_x, &orient_x, &look);
	}
	else
	{
		SetVector(&look, 0.f, 0.f, 1000.f);
		m.MultVectMat(&look);
		VecAdd(&look, &pos, &look);
	}

	SetVector(&up, 0.f, 1.f, 0.f);
	m.MultVectMat(&up);

	err = PPC_STUB(rsiSetCamera)(CTXT,
				rsiTCameraPos,    &pos,
				rsiTCameraViewUp, &up,
				rsiTCameraLook,   &look,
				rsiTDone);
	if(err)
		return err;

	if(flags & OBJECT_CAMERA_VFOV)
		vfov = hfov*global.yres/global.xres;

	if(flags & OBJECT_CAMERA_FOCUSTRACK)
	{
		VecSub(&look, &pos, &look);
		focaldist = VecNormalize(&look);
	}

	rsiflags = 0;

	if (flags & OBJECT_CAMERA_FASTDOF)
		rsiflags |= rsiFCameraFastDOF;

	return PPC_STUB(rsiSetCamera)(CTXT,
		rsiTCameraPos,       &pos,
		rsiTCameraHFov,      atan(hfov) * 2 * INV_PI_180,
		rsiTCameraVFov,      atan(vfov) * 2 * INV_PI_180,
		rsiTCameraFocalDist, focaldist,
		rsiTCameraAperture,  aperture,
		rsiTCameraFlags,     rsiflags,
		rsiTDone);
}
Example #9
0
//构造末端所需要的力F,输入起始点P,垂足Pp,P与Pp的距离d,控制参数an,输出力F
void MakeF(const float *P, const float *Pp, const float d, const float an, float* F)
{
    float para = an * log(1+d);
    float Fn[3] = {0,0,0};
    float Ft[3] = {0,0,0};
    Fn[0] = para * (Pp[0]-P[0]);
    Fn[1] = para * (Pp[1]-P[1]);
    Fn[2] = para * (Pp[2]-P[2]);
    VecAdd(Fn,Ft,F);
}
Example #10
0
typename TAAPosVRT::ValueType
CalculateCenter(TIterator begin, TIterator end, TAAPosVRT& aaPos)
{
	int counter = 0;
	typename TAAPosVRT::ValueType center;
	VecSet(center, 0);
	for(TIterator iter = begin; iter != end; ++iter, ++counter)
		VecAdd(center, center, CalculateCenter(*iter, aaPos));
		
	if(counter > 0)
		VecScale(center, center, 1./(number)counter);
		
	return center;
}
Example #11
0
/*************
 * DESCRIPTION:   Modify given normal by "bumping" it.
 * INPUT:         norm        normal
 *                dpdu        delta u
 *                dpdv        delta v
 *                fu
 *                fv
 * OUTPUT:        none
 *************/
void MakeBump(VECTOR *norm, VECTOR *dpdu, VECTOR *dpdv, float fu, float fv)
{
    VECTOR tmp1, tmp2;

    VecCross(norm, dpdv, &tmp1);
    tmp1.x *= fu;
    tmp1.y *= fu;
    tmp1.z *= fu;
    VecCross(norm, dpdu, &tmp2);
    tmp2.x *= fv;
    tmp2.y *= fv;
    tmp2.z *= fv;
    VecSub(&tmp1, &tmp2, &tmp1);
    VecAdd(norm, &tmp1, norm);
    VecNormalizeNoRet(norm);
}
Example #12
0
/*
 * Compute intensity ('color') of extended light source 'lp' from 'pos'.
 */
static int
ExtendedIntens(
        LightRef        lr, 
        Color           *lcolor, 
        ShadowCache     *cache,
        Ray             *ray,
        Float           /*dist*/, 
        int             noshadow,
        Color           *color)
{
    Extended        *lp = (Extended*)lr;
	Float jit, vpos, upos, lightdist;
	Ray newray;
	Vector Uaxis, Vaxis, ldir;

	if (noshadow) {
		*color = *lcolor;
		return TRUE;
	}

	newray = *ray;
	/*
	 * Determinte two orthoganal vectors that lay in the plane
	 * whose normal is defined by the vector from the center
	 * of the light source to the point of intersection and
	 * passes through the center of the light source.
 	 */
	VecSub(lp->pos, ray->pos, &ldir);
	VecCoordSys(&ldir, &Uaxis, &Vaxis);

	jit = 2. * lp->radius * Sampling.spacing;

	/*
	 * Sample a single point, determined by SampleNumber,
	 * on the extended source.
	 */
	vpos = -lp->radius + (ray->sample % Sampling.sidesamples)*jit;
	upos = -lp->radius + (ray->sample / Sampling.sidesamples)*jit;
	vpos += nrand() * jit;
	upos += nrand() * jit;
	VecComb(upos, Uaxis, vpos, Vaxis, &newray.dir);
	VecAdd(ldir, newray.dir, &newray.dir);
	lightdist = VecNormalize(&newray.dir);

	return !Shadowed(color, lcolor, cache, &newray,
		lightdist, noshadow);
}
Example #13
0
void FractalProjector::
new_vertex(Vertex* vrt, Edge* parent)
{
//	set the vertex to the center by calling the parents method
	RefinementCallbackLinear<APosition>::new_vertex(vrt, parent);

//	calculate the normal of the edge
	vector3 n;
	CalculateNormal(n, *m_pGrid, parent, m_aaPos);
//	first scale it to the same length as the edge, then scale it with the
//	given scaleFac
	number len = VecDistance(m_aaPos[parent->vertex(0)], m_aaPos[parent->vertex(1)]);
	VecScale (n, n, m_scaleFac * len);

//	offset the vertex by the calculated normal
	VecAdd(m_aaPos[vrt], m_aaPos[vrt], n);
}
Example #14
0
//末端力转化到关节力矩,输入末端轨迹R1,R2,l1,l2,输出ts,te
void TransformF(const float* R1, const float* R2, const float* l1,const float* l2, const float *F, float *ts, float *te)
{
    float P1[3];
    float P2[3];
    float P[3];
    MatMultVec(R1, l1, P1);
    MatMultVec(R2, l2, P2);
    VecAdd(P1,P2,P);
    VecCross(F,P,ts);

    float tmp[3];
    VecCross(F,P2,tmp);
    te[0] = -VecDot(tmp,R1);
    te[1] = 0;
    te[2] = 0;

}
Example #15
0
std::vector<std::vector<double>> netForce(){
	
	size_t n = bodies.size();
	double totMass = 1.0;
	std::vector<double> pos = {0, 0, 0};
	std::vector<std::vector<double>> output;
	
	for(unsigned int i = 0; i < n; ++i){
		totMass *= bodies[i].getMass();
		for(unsigned int j = 0; j < n && i!=j; ++j){
			double magnitude = mag(VecSub(bodies[i].getPos(), bodies[j].getPos()));
			pos = VecAdd(pos, VecScaleMulti((VecSub(bodies[i].getPos(), bodies[j].getPos())), (1.0/(magnitude * magnitude * magnitude))));
		}
		output.push_back(VecScaleMulti(pos, totMass*G));
	}
	return output;
}
Example #16
0
void CalculateVertexNormal(vector3& nOut, Grid& grid, Vertex* vrt, TAAPosVRT& aaPos)
{
//	set all normal to zero
	nOut = vector3(0, 0, 0);

//	loop through all associated faces, calculate their normal and add them to thee normal
	Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrt);
	for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrt);
		iter != iterEnd; iter++)
	{
		vector3 vN;
		CalculateNormal(vN, *iter, aaPos);
		VecAdd(nOut, nOut, vN);
	}

	VecNormalize(nOut, nOut);
}
Example #17
0
typename TAPosition::ValueType
CalculateBarycenter(TVrtIter vrtsBegin, TVrtIter vrtsEnd,
					Grid::VertexAttachmentAccessor<TAPosition>& aaPos)
{
	typename TAPosition::ValueType v;
	VecSet(v, 0);
	int counter = 0;
	for(TVrtIter iter = vrtsBegin; iter != vrtsEnd; ++iter)
	{
		VecAdd(v,v,aaPos[*iter]);
		counter++;
	}

	if(counter>0)
		VecScale(v,v,1.f/counter);
	return v;
}
Example #18
0
void JTModelAppend(JTModel *Self, DefNode *Parent, DefNode *Node)
{
    VNode *view;
    Vec *vec = Parent->Children;
    if (!vec)
    {
	vec = VecInit(NULL);
	Parent->Children = vec;
    }
    VecAdd(vec, Node);
    view = Parent->tnode.NextView;
    Node->Parent = Parent;
    while (view)
    {
	JTreeAddView(view->Tree, view, &Node->tnode);
	view = view->NextView;
    }
}
Example #19
0
std::vector<double> accelFunc(std::vector<double> pos, std::vector<double> vel, double t){

	std::vector<double> accel = {0, 0, 0};

	double r;

	for(size_t i=0; i<bodies.size();++i){
		r = mag(VecSub(pos, bodies[i].getPos()));
		if(r==0){ // If comparing body is same as current body
			continue;
		}else{ // If comparing to foreign body
			//accel+=bodies[i].getMass()/(r*r*r);
			accel= VecAdd(accel, VecScaleMulti(VecSub(pos, bodies[i].getPos()), (G*bodies[i].getMass()/(r*r*r))  ) );
		}
	}

	return accel;
}
Example #20
0
/*************
 * DESCRIPTION:   Update brush parameters
 * INPUT:         time     current time
 * OUTPUT:        none
 *************/
void BRUSH::Update(const float time)
{
	TIME t;
	VECTOR a;

	if((actor->time.begin != this->time) || (actor->time.end != time))
	{
		t.begin = this->time;
		t.end = time;
		actor->Animate(&t);
	}
	actor->matrix->MultVectMat(&pos);

	a = actor->act_align;
	VecAdd(&a,&align,&a);
	CalcOrient(&a, &orient_x, &orient_y, &orient_z);
	this->time = time;
}
Example #21
0
typename ntree<tree_dim, world_dim, elem_t, common_data_t>::vector_t
ntree<tree_dim, world_dim, elem_t, common_data_t>::
calculate_center_of_mass(Node& node)
{
	vector_t centerOfMass;
	VecSet(centerOfMass, 0);

	for(size_t entryInd = node.firstEntryInd; entryInd != s_invalidIndex;){
		Entry& entry = m_entries[entryInd];

		vector_t center;
		traits::calculate_center(center, entry.elem, m_commonData);
		VecAdd(centerOfMass, centerOfMass, center);
		entryInd = entry.nextEntryInd;
	}

	if(node.numEntries > 0)
		VecScale(centerOfMass, centerOfMass, (real_t)1 / (real_t)node.numEntries);

	return centerOfMass;
}
Example #22
0
int main(){

    int maxsize = 1000;
    std::vector<int>num1;
    std::vector<int>num2;
    std::vector<int>num3;

    num1.push_back(1);
    num2.push_back(1);

    int counter = 2;

    while(num1.size()+1 <= maxsize){
    num3 = num1;
    num1 = VecAdd(num2, num3);
    num2 = num3;

    counter++;

    }
    std::cout << counter;
}
Example #23
0
void CalculateBoundaryVertexNormal3D(vector3& nOut, Grid& grid, Vertex* vrt,
						   	   	     TAAPosVRT& aaPos)
{
//	The algorithm is a little cumbersome. However, through this setup, we
//	make sure that the orientation of the normal indeed points outwards,
//	based only on the topology.

//	set nOut to 0
	VecSet(nOut, 0);

//	iterate over associated volumes
	std::vector<Volume*> vols;
	CollectAssociated(vols, grid, vrt);

	FaceDescriptor fd;
	for(size_t i_vol = 0; i_vol < vols.size(); ++i_vol){
		Volume* v = vols[i_vol];
	//	check for each side of f whether it is a boundary edge
		for(size_t i_side = 0; i_side < v->num_sides(); ++i_side){
			if(IsBoundaryFace3D(grid, grid.get_face(v, i_side))){
				v->face_desc(i_side, fd);

			//	make sure that fd contains the given vertex
				if(!FaceContains(&fd, vrt))
					continue;

			//	the normal pointing outwards is clearly defined from the
			//	orientation of the face descriptor
				vector3 n;
				CalculateNormal(n, &fd, aaPos);
				VecAdd(nOut, nOut, n);
			}
		}
	}

	VecNormalize(nOut, nOut);
}
Example #24
0
VOID	PolyRead(OBJECT *po, FILE *pf)
	{
	INT	i, j;			/* Indices.			     */
	INT	instat; 		/* Read status. 		     */
	INT	*vindex;
	INT	totalverts;		/* Total # of vertices in poly mesh. */
	CHAR	normstr[5];		/* Face/vertex normal flag string.   */
	BOOL	pnormals;		/* Face normals present?	     */
	VEC3	pnorm;			/* Polygon normal accumulator.	     */
	VEC3	*vlist, *vptr, *vp;	/* Ptr to vertex list.		     */
	VEC3	*vptmp, *vptmp2;	/* Ptr to vertex list.		     */
	VEC3	tmppnt, tmppnt2, cross;
	POLY	*pp;			/* Ptr to polygon data. 	     */
	ELEMENT *pe;			/* Ptr to polygon element.	     */


	pe = po->pelem;

	/* Allocate space for object data. */

	instat = fscanf(pf, "%ld", &totalverts);

	if (instat != 1)
		{
		printf("Error in PolyRead: totalverts.\n");
		exit(-1);
		}

	pp    = GlobalMalloc(sizeof(POLY)*po->numelements,  "poly.c");
	vlist = GlobalMalloc(sizeof(VEC3)*(totalverts + 1), "poly.c");
	vptr  = vlist;


	/* Are polygon face normals supplied? */

	instat = fscanf(pf, "%s\n", normstr);

	if (instat != 1)
		{
		printf("Error in PolyRead: face normal indicator.\n");
		exit(-1);
		}

	pnormals = (normstr[2] == 'y' ? TRUE : FALSE);


	/* Read vertex list. */

	for (i = 0; i < totalverts; i++)
		{
		instat = fscanf(pf, "%lf %lf %lf", &(*vptr)[0], &(*vptr)[1], &(*vptr)[2]);

		if (instat != 3)
			{
			printf("Error in PolyRead: vertex %ld.\n", i);
			exit(-1);
			}

		vptr++;
		}


	(*vptr)[0] = HUGE_REAL;
	(*vptr)[1] = HUGE_REAL;
	(*vptr)[2] = HUGE_REAL;


	/* Read polygon list. */

	for (i = 0; i < po->numelements; i++)
		{
		instat = fscanf(pf, "%ld", &(pp->nverts));

		if (instat != 1)
			{
			printf("Error in PolyRead: vertex count.\n");
			exit(-1);
			}

		if (pp->nverts > MAX_VERTS)
			{
			printf("Polygon vertex count, %ld, exceeds maximum.\n", pp->nverts);
			exit(-1);
			}

		if (pnormals)
			{
			instat = fscanf(pf, " %lf %lf %lf", &(pp->norm[0]), &(pp->norm[1]), &(pp->norm[2]));

			if (instat != 3)
				{
				printf("Error in PolyRead: face normal %ld.\n", i);
				exit(-1);
				}
			}

		pp->vptr   = vlist;
		pp->vindex = GlobalMalloc(sizeof(INT)*pp->nverts, "poly.c");
		vindex	   = pp->vindex;

		for (j = 0; j < pp->nverts; j++)
			{
			instat = fscanf(pf, "%ld", vindex++);

			if (instat != 1)
				{
				printf("Error in PolyRead: vertex index %ld.\n", i);
				exit(-1);
				}
			}

		/* If not supplied, calculate plane normal. */

		vindex = pp->vindex;
		vptr   = vlist;

		if (!pnormals)
			{
			vp = vptr + (*vindex);
			VecZero(pnorm);

			for (j = 0; j < pp->nverts - 2; j++)
				{
				vptmp  = vptr + (*(vindex + 1));
				vptmp2 = vptr + (*(vindex + 2));

				VecSub(tmppnt,	(*vptmp),  (*vp));
				VecSub(tmppnt2, (*vptmp2), (*vptmp));

				VecCross(cross, tmppnt, tmppnt2);
				VecAdd(pnorm,	pnorm,	cross);

				vp = vptmp;
				vindex += 1;
				}

			VecSub(tmppnt, (*vptmp2), (*vp));
			vindex	= pp->vindex;
			vp	= vptr + (*vindex);

			VecSub(tmppnt2, (*vp), (*vptmp2));
			VecCross(cross, tmppnt, tmppnt2);
			VecAdd(pnorm, pnorm, cross);

			vp	= vptr + (*vindex);
			VecSub(tmppnt, (*vp), (*vptmp2));
			vptmp	= vptr + (*(vindex + 1));

			VecSub(tmppnt2, (*vptmp), (*vp));
			VecCross(cross, tmppnt, tmppnt2);
			VecAdd(pnorm, pnorm, cross);
			VecScale(pp->norm, 1.0/VecLen(pnorm), pnorm);
			}


		/* Calculate plane equation d. */

		vp = pp->vptr + *(pp->vindex);
		pp->d = -(pp->norm[0]*(*vp)[0] + pp->norm[1]*(*vp)[1] + pp->norm[2]*(*vp)[2]);

		pe->data   = (CHAR *)pp;
		pe->parent = po;

		PolyElementBoundBox(pe, pp);

		pp++;
		pe++;
		}
	}
Example #25
0
//求雅克比矩阵。
void SolveJacob(const float* MechPara, const float* R1, const float* R2, float* jacob_s, float* jacob_e)
{
    float A1[3],A2[3],A3[3],A4[3],B1[3],B2[3],B3[3],B4[3],B5[3],B6[3],C1[3],C2[3];
    const float l1 = MechPara[0];
    //const float l2 = MechPara[1];
    const float d1 = MechPara[2];
    const float r1 = MechPara[3];
    const float d2 = MechPara[4];
    const float r2 = MechPara[5];
    const float d3 = MechPara[6];
    const float r3 = MechPara[7];
    const float alphaa1 = MechPara[8];
    const float psta2 = MechPara[9];
    const float psta3 = MechPara[10];
    const float alphaa4 = MechPara[11];
    const float alphab1 = MechPara[12];
    const float alphab2 = MechPara[13];
    const float alphab3 = MechPara[14];
    const float alphab4 = MechPara[15];
    const float alphab5 = MechPara[16];
    const float alphab6 = MechPara[17];
    const float alphac1 = MechPara[18];
    const float alphac2 = MechPara[19];
    SolveTmpVec(r1,alphaa1,d1,A1);
    SolveTmpVec(r1,alphaa4,d1,A4);
    SolveTmpVec(r2,alphab1,d2,B1);
    SolveTmpVec(r2,alphab2,d2,B2);
    SolveTmpVec(r2,alphab3,d2,B3);
    SolveTmpVec(r2,alphab4,d2,B4);
    SolveTmpVec(r2,alphab5,d2,B5);
    SolveTmpVec(r2,alphab6,d2,B6);
    SolveTmpVec(r3,alphac1,d3,C1);
    SolveTmpVec(r3,alphac2,d3-84,C2);
    A2[0] = psta2;
    A2[1] = r1;
    A2[2] = d1;
    A3[0] = psta3;
    A3[1] = -r1;
    A3[2] = d1;
    float A[3] = {0,0,0};
    float B[3];
    float tmpl[3];
    tmpl[0] = tmpl[1] = 0;
    tmpl[2] = l1;
    MatMultVec(R1,tmpl,B);

    float B1_r[3], B2_r[3], B3_r[3], B4_r[3], B5_r[3], B6_r[3], C1_r[3], C2_r[3], ld1[3], ld2[3], ld3[3], ld4[3], ld5[3], ld6[3];
    MatMultVec(R1,B1,B1_r);
    MatMultVec(R1,B2,B2_r);
    MatMultVec(R1,B3,B3_r);
    MatMultVec(R1,B4,B4_r);
    MatMultVec(R1,B5,B5_r);
    MatMultVec(R1,B6,B6_r);

    MatMultVec(R2,C1,C1_r);
    MatMultVec(R2,C2,C2_r);
    VecAdd(B,C1_r,C1_r);
    VecAdd(B,C2_r,C2_r);

    VecSub(B1_r,A1,ld1);
    VecSub(B2_r,A2,ld2);
    VecSub(B3_r,A3,ld3);
    VecSub(B4_r,A4,ld4);
    VecSub(C1_r,B5,ld5);
    VecSub(C2_r,B6,ld6);
    Normalization(ld1);
    Normalization(ld2);
    Normalization(ld3);
    Normalization(ld4);
    Normalization(ld5);
    Normalization(ld6);

    float B1_r_A[3], B2_r_A[3], B3_r_A[3], B4_r_A[3], C1_r_B[3], C2_r_B[3];
    VecSub(B1_r,A,B1_r_A);
    VecSub(B2_r,A,B2_r_A);
    VecSub(B3_r,A,B3_r_A);
    VecSub(B4_r,A,B4_r_A);
    VecSub(C1_r,B,C1_r_B);
    VecSub(C2_r,B,C2_r_B);

    float tmp[3];
    VecCross(B1_r_A,ld1,tmp);
    jacob_s[0] = tmp[0];
    jacob_s[4] = tmp[1];
    jacob_s[8] = tmp[2];
    VecCross(B2_r_A,ld2,tmp);
    jacob_s[1] = tmp[0];
    jacob_s[5] = tmp[1];
    jacob_s[9] = tmp[2];
    VecCross(B3_r_A,ld3,tmp);
    jacob_s[2] = tmp[0];
    jacob_s[6] = tmp[1];
    jacob_s[10] = tmp[2];
    VecCross(B4_r_A,ld4,tmp);
    jacob_s[3] = tmp[0];
    jacob_s[7] = tmp[1];
    jacob_s[11] = tmp[2];
    VecCross(C1_r_B,ld5,tmp);
    jacob_e[0] = tmp[0];
    jacob_e[2] = tmp[1];
    jacob_e[4] = tmp[2];
    VecCross(C2_r_B,ld6,tmp);
    jacob_e[1] = tmp[0];
    jacob_e[3] = tmp[1];
    jacob_e[5] = tmp[2];

}
Example #26
0
int Refine(int* newIndsOut, int* newEdgeVrts, bool& newCenterOut,
		   vector3* corners, bool*)
{
	newCenterOut = false;
//	If a refinement rule is not implemented, fillCount will stay at 0.
//	Before returning, we'll check, whether fillCount is at 0 and will
//	perform refinement with an additional vertex in this case.

//	corner status is used to mark vertices, which are connected to refined edges
//	the value tells, how many associated edges are refined.
	int cornerStatus[4] = {0, 0, 0, 0};

//	here we'll store the index of each edge, which will be refined.
//	Size of the valid sub-array is numNewVrts, which is calculated below.
	int refEdgeInds[NUM_EDGES];

//	count the number of new vertices and fill newVrtEdgeInds
	int numNewVrts = 0;
	for(int i = 0; i < NUM_EDGES; ++i){
		if(newEdgeVrts[i]){
			refEdgeInds[numNewVrts] = i;
			++numNewVrts;

		//	adjust corner status of associated vertices
			const int* evi = EDGE_VRT_INDS[i];
			++cornerStatus[evi[0]];
			++cornerStatus[evi[1]];
		}
	}

//	the fillCount tells how much data has already been written to newIndsOut.
	int fillCount = 0;

//	depending on the number of new vertices, we will now apply different
//	refinement rules. Further distinction may have to be done.
	switch(numNewVrts){
		case 0:
		{
		//	simply put the default tetrahedron back to newIndsOut
			newIndsOut[fillCount++] = GOID_TETRAHEDRON;
			newIndsOut[fillCount++] = 0;
			newIndsOut[fillCount++] = 1;
			newIndsOut[fillCount++] = 2;
			newIndsOut[fillCount++] = 3;
		}break;

		case 1:
		{
			int refEdgeInd = refEdgeInds[0];
		//	the two faces which are not connected to the refined edge
		//	serve as bottom for the new tetrahedrons.
			for(int i_face = 0; i_face < NUM_FACES; ++i_face){
				if(!FACE_CONTAINS_EDGE[i_face][refEdgeInd]){
					const int* fvi = FACE_VRT_INDS[i_face];

					newIndsOut[fillCount++] = GOID_TETRAHEDRON;
					newIndsOut[fillCount++] = fvi[0];
					newIndsOut[fillCount++] = fvi[1];
					newIndsOut[fillCount++] = fvi[2];
					newIndsOut[fillCount++] = NUM_VERTICES + refEdgeInd;
				}
			}
		}break;

		case 2:
		{
		//	two types exist: The two refined edges share a vertex or not.
			if(OPPOSED_EDGE[refEdgeInds[0]] == refEdgeInds[1]){
			//	they do not share an edge
			//	we create a local order from refEdgeInds[0], which
			//	always has to be an edge in the base-triangle and
			//	refEdgeInds[1], which always connects a base-corner with
			//	the top.
				const int v0 = EDGE_VRT_INDS[refEdgeInds[0]][0];
				const int v1 = EDGE_VRT_INDS[refEdgeInds[0]][1];
				const int v2 = EDGE_VRT_INDS[refEdgeInds[1]][0];
				const int v3 = EDGE_VRT_INDS[refEdgeInds[1]][1];
				const int n0 = refEdgeInds[0] + NUM_VERTICES;
				const int n1 = refEdgeInds[1] + NUM_VERTICES;

			//	from this local order we can now construct the 4 new tetrahedrons.
				int& fi = fillCount;
				int* inds = newIndsOut;
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v0;	inds[fi++] = n0;
				inds[fi++] = v2; 	inds[fi++] = n1;

				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v0;	inds[fi++] = n0;
				inds[fi++] = n1; 	inds[fi++] = v3;

				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = n0;	inds[fi++] = v1;
				inds[fi++] = v2; 	inds[fi++] = n1;

				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = n0;	inds[fi++] = v1;
				inds[fi++] = n1; 	inds[fi++] = v3;
			}
			else{
			//	they share an edge
			//	We have to create a pyramid and a tetrahedron.
			//	get the triangle, which contains both refEdges
				int refTriInd = FACE_FROM_EDGES[refEdgeInds[0]][refEdgeInds[1]];
				const int* f = FACE_VRT_INDS[refTriInd];

			//	find the edge (v0, v1) in refTri, which won't be refined
				int v0 = -1; int v1 = -1; int v2 = -1;
				for(int i = 0; i < 3; ++i){
					v0 = f[i];
					v1 = f[(i+1)%3];
					v2 = f[(i+2)%3];
					if(cornerStatus[v0] == 1 && cornerStatus[v1] == 1)
						break;
				}

			//	make sure that v2 is connected to two refined edges
				assert(cornerStatus[v2] == 2);

			//	get the new vertex on edge v1v2 and on v2v0
				int v1v2 = EDGE_FROM_VRTS[v1][v2] + NUM_VERTICES;
				int v2v0 = EDGE_FROM_VRTS[v2][v0] + NUM_VERTICES;

			//	get the top (vertex with cornerState 0)
				int vtop = -1;
				for(int i = 0; i < NUM_VERTICES; ++i){
					if(cornerStatus[i] == 0){
						vtop = i;
						break;
					}
				}

			//	now lets build the pyramid
				int& fi = fillCount;
				int* inds = newIndsOut;
				inds[fi++] = GOID_PYRAMID;
				inds[fi++] = v0;	inds[fi++] = v1;
				inds[fi++] = v1v2; 	inds[fi++] = v2v0;
				inds[fi++] = vtop;

			//	and now the terahedron
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v2;	inds[fi++] = vtop;
				inds[fi++] = v2v0;	inds[fi++] = v1v2;
			}
		}break;

		case 3:
		{
		//	different possibilities exist. First we'll treat the one,
		//	where all new vertices lie on the edges of one triangle.
		//	Note that refTriInd could be -1 after the call.
			int refTriInd = FACE_FROM_EDGES[refEdgeInds[0]][refEdgeInds[1]];
			if(refTriInd == FACE_FROM_EDGES[refEdgeInds[1]][refEdgeInds[2]])
			{
			//	all three lie in one plane (refTriInd has to be != -1 to get here)
			//	get the top (vertex with cornerState 0)
				int vtop = -1;
				for(int i = 0; i < NUM_VERTICES; ++i){
					if(cornerStatus[i] == 0){
						vtop = i;
						break;
					}
				}

				const int* f = FACE_VRT_INDS[refTriInd];

			//	create four new tetrahedrons
				const int v0 = f[0]; const int v1 = f[1]; const int v2 = f[2];
				const int v0v1 = EDGE_FROM_VRTS[v0][v1] + NUM_VERTICES;
				const int v1v2 = EDGE_FROM_VRTS[v1][v2] + NUM_VERTICES;
				const int v2v0 = EDGE_FROM_VRTS[v2][v0] + NUM_VERTICES;

				int& fi = fillCount;
				int* inds = newIndsOut;
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v0;	inds[fi++] = vtop;
				inds[fi++] = v0v1;	inds[fi++] = v2v0;
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v1;	inds[fi++] = vtop;
				inds[fi++] = v1v2;	inds[fi++] = v0v1;
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v2;	inds[fi++] = vtop;
				inds[fi++] = v2v0;	inds[fi++] = v1v2;
				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v0v1;	inds[fi++] = vtop;
				inds[fi++] = v1v2;	inds[fi++] = v2v0;
			}
			else{
			//	we have to further distinguish.
			//	gather the corners with corner-state 3 and corner state 1
				int corner3 = -1;
				int freeCorner[NUM_VERTICES];
				int freeCount = 0;
				for(int i = 0; i < NUM_VERTICES; ++i){
					if(cornerStatus[i] == 3)
						corner3 = i;
					else
						freeCorner[freeCount++] = i;
				}

				if(corner3 != -1){
				//	a corner with corner state 3 exists.
					assert(freeCount == 3);

				// get the face which won't be refined (required for correct orientation)
					int freeTriInd = FACE_FROM_VRTS[freeCorner[0]][freeCorner[1]]
												   [freeCorner[2]];

				//	the free tri is the new base, corner3 the top
					const int* f = FACE_VRT_INDS[freeTriInd];
					int v2v3 = EDGE_FROM_VRTS[f[2]][corner3] + NUM_VERTICES;
					int v1v3 = EDGE_FROM_VRTS[f[1]][corner3] + NUM_VERTICES;
					int v0v3 = EDGE_FROM_VRTS[f[0]][corner3] + NUM_VERTICES;

				//	add a prism and a tetrahedron
					int& fi = fillCount;
					int* inds = newIndsOut;
					inds[fi++] = GOID_PRISM;
					inds[fi++] = f[0]; inds[fi++] = f[1]; inds[fi++] = f[2];
					inds[fi++] = v0v3; inds[fi++] = v1v3; inds[fi++] = v2v3;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = v2v3; inds[fi++] = corner3; inds[fi++] = v0v3;
					inds[fi++] = v1v3;
				}
			}
		}break;

		case 4:
		{
		//	multiple settings with 4 refined edges exist.
		//	Either two opposing edges are not marked (case all2 == true)
		//	or the two unmarked edges are contained in 1 triangle

		//	check whether all vertices have corner state 2
			bool all2 = true;
			for(int i = 0; i < NUM_VERTICES; ++i){
				if(cornerStatus[i] !=2){
					all2 = false;
					break;
				}
			}

			if(all2){
			//	we've got a straight cut.
			//	we'll rotate the tetrahedron around the tip so, that edge 2 won't be refined.
				int steps = 0;
				if(!newEdgeVrts[EDGE_FROM_VRTS[0][1]])
					steps = 2;
				else if(!newEdgeVrts[EDGE_FROM_VRTS[1][2]])
					steps = 1;

				int t[NUM_VERTICES] = {0, 1, 2, 3};
				TetRotation(t, 3, steps);

				const int v0v1 = EDGE_FROM_VRTS[t[0]][t[1]] + NUM_VERTICES;
				const int v1v2 = EDGE_FROM_VRTS[t[1]][t[2]] + NUM_VERTICES;
				const int v0v3 = EDGE_FROM_VRTS[t[0]][t[3]] + NUM_VERTICES;
				const int v2v3 = EDGE_FROM_VRTS[t[2]][t[3]] + NUM_VERTICES;

				assert(newEdgeVrts[v0v1 - NUM_VERTICES]);
				assert(newEdgeVrts[v1v2 - NUM_VERTICES]);
				assert(newEdgeVrts[v0v3 - NUM_VERTICES]);
				assert(newEdgeVrts[v2v3 - NUM_VERTICES]);

			//	now build two prisms
				int& fi = fillCount;
				int* inds = newIndsOut;

				inds[fi++] = GOID_PRISM;
				inds[fi++] = t[0];	inds[fi++] = v0v3;	inds[fi++] = v0v1;
				inds[fi++] = t[2];	inds[fi++] = v2v3;	inds[fi++] = v1v2;

				inds[fi++] = GOID_PRISM;
				inds[fi++] = t[1];	inds[fi++] = v1v2;	inds[fi++] = v0v1;
				inds[fi++] = t[3];	inds[fi++] = v2v3;	inds[fi++] = v0v3;
			}
			else{
			//	one corner has state 1, one has state 3 and two have state 2.
			//	Rotate the tet so that 1 is at the top and 4 is at the origin
				int I[NUM_VERTICES] = {0, 1, 2, 3};

				int s1 = -1;
				for(int i = 0; i < 4; ++i){
					if(cornerStatus[i] == 1){
						s1 = i;
						break;
					}
				}

				if(s1 != 3){
					const int fixedPoint = (s1 + 2) % 3;
					TetRotation(I, fixedPoint, 1);
				}

				if(cornerStatus[I[1]] == 3)
					TetRotation(I, 3, 2);
				else if(cornerStatus[I[2]] == 3)
					TetRotation(I, 3, 1);

			//	indices of edge-center vertices
				const int v01 = EDGE_FROM_VRTS[I[0]][I[1]] + NUM_VERTICES;
				const int v02 = EDGE_FROM_VRTS[I[0]][I[2]] + NUM_VERTICES;
				const int v03 = EDGE_FROM_VRTS[I[0]][I[3]] + NUM_VERTICES;
				const int v12 = EDGE_FROM_VRTS[I[1]][I[2]] + NUM_VERTICES;

				int& fi = fillCount;
				int* inds = newIndsOut;

				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = I[0];	inds[fi++] = v01;
				inds[fi++] = v02;	inds[fi++] = v03;

				inds[fi++] = GOID_TETRAHEDRON;
				inds[fi++] = v01;	inds[fi++] = v12;
				inds[fi++] = v02;	inds[fi++] = v03;

				inds[fi++] = GOID_PYRAMID;
				inds[fi++] = I[3];	inds[fi++] = I[1];
				inds[fi++] = v01;	inds[fi++] = v03;
				inds[fi++] = v12;

				inds[fi++] = GOID_PYRAMID;
				inds[fi++] = I[2];	inds[fi++] = I[3];
				inds[fi++] = v03;	inds[fi++] = v02;
				inds[fi++] = v12;
			}
		}break;

		case 5:{
		//	only one edge is not marked for refinement
			int unmarkedEdge = 0;
			for(int i = 0; i < NUM_EDGES; ++i){
				if(!newEdgeVrts[i]){
					unmarkedEdge = i;
					break;
				}
			}

			int uei0 = EDGE_VRT_INDS[unmarkedEdge][0];
			int uei1 = EDGE_VRT_INDS[unmarkedEdge][1];

		//	orientate the tetrahedron so that the unmarked edge connects
		//	vertices 2 and 3
			int I[NUM_VERTICES] = {0, 1, 2, 3};
		//	if the unmarked edge lies in the base triangle, we'll first have to
		//	rotate so that it connects a base-vertex with the top
			if(unmarkedEdge < 3){
				const int fixedPoint = (uei1 + 1) % 3;
				TetRotation(I, fixedPoint, 1);
				int IInv[4];
				InverseTetTransform(IInv, I);

				uei0 = IInv[uei0];
				uei1 = IInv[uei1];
				unmarkedEdge = EDGE_FROM_VRTS[uei0][uei1];
			}

		//	now rotate the tet to its final place
			if(unmarkedEdge == 3)
				TetRotation(I, 3, 2);
			else if(unmarkedEdge == 4)
				TetRotation(I, 3, 1);

		//	We obtained the final permutation I. Now create new elements
		//	indices of edge-center vertices
			const int v01 = EDGE_FROM_VRTS[I[0]][I[1]] + NUM_VERTICES;
			const int v02 = EDGE_FROM_VRTS[I[0]][I[2]] + NUM_VERTICES;
			const int v03 = EDGE_FROM_VRTS[I[0]][I[3]] + NUM_VERTICES;
			const int v12 = EDGE_FROM_VRTS[I[1]][I[2]] + NUM_VERTICES;
			const int v13 = EDGE_FROM_VRTS[I[1]][I[3]] + NUM_VERTICES;

			int& fi = fillCount;
			int* inds = newIndsOut;

			inds[fi++] = GOID_TETRAHEDRON;
			inds[fi++] = I[0];	inds[fi++] = v01;
			inds[fi++] = v02;	inds[fi++] = v03;

			inds[fi++] = GOID_TETRAHEDRON;
			inds[fi++] = I[1];	inds[fi++] = v12;
			inds[fi++] = v01;	inds[fi++] = v13;

			inds[fi++] = GOID_PYRAMID;
			inds[fi++] = v02;	inds[fi++] = v12;
			inds[fi++] = v13;	inds[fi++] = v03;
			inds[fi++] = v01;

			inds[fi++] = GOID_PRISM;
			inds[fi++] = v02;	inds[fi++] = v12;	inds[fi++] = I[2];
			inds[fi++] = v03;	inds[fi++] = v13;	inds[fi++] = I[3];


		}break;

	//	REGULAR REFINEMENT
		case 6:
		{
		//	depending on the user specified global refinement rule, we will now apply different
		//	refinement rules.
			switch(g_refinementRule){
				case STANDARD:
				{
					int& fi = fillCount;
					int* inds = newIndsOut;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 0;					inds[fi++] = NUM_VERTICES + 0;
					inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 3;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 1;					inds[fi++] = NUM_VERTICES + 1;
					inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 4;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 2;					inds[fi++] = NUM_VERTICES + 2;
					inds[fi++] = NUM_VERTICES + 1;	inds[fi++] = NUM_VERTICES + 5;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = NUM_VERTICES + 3;	inds[fi++] = NUM_VERTICES + 4;
					inds[fi++] = NUM_VERTICES + 5;	inds[fi++] = 3;

				//	for the remaining four tetrahedrons, we'll choose the shortest diagonal
					int bestDiag = 2;
					if(corners){
					//	there are three diagonals between the following edge-centers:
					//	0-5, 1-3, 2-4
						vector3 c1, c2;

					//	0-5
						VecAdd(c1, corners[0], corners[1]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[2], corners[3]);
						VecScale(c2, c2, 0.5);
						number d05 = VecDistanceSq(c1, c2);

					//	1-3
						VecAdd(c1, corners[1], corners[2]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[0], corners[3]);
						VecScale(c2, c2, 0.5);
						number d13 = VecDistanceSq(c1, c2);

					//	2-4
						VecAdd(c1, corners[0], corners[2]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[1], corners[3]);
						VecScale(c2, c2, 0.5);
						number d = VecDistanceSq(c1, c2);

						if(d13 < d){
							bestDiag = 1;
							d = d13;
						}
						if(d05 < d){
							bestDiag = 0;
						}
					}

					switch(bestDiag){
					case 0:// diag: 0-5
						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 1;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 5;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 1;	inds[fi++] = NUM_VERTICES + 4;
						inds[fi++] = NUM_VERTICES + 5;	inds[fi++] = NUM_VERTICES + 0;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 5;
						inds[fi++] = NUM_VERTICES + 3;	inds[fi++] = NUM_VERTICES + 0;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 3;
						inds[fi++] = NUM_VERTICES + 4;	inds[fi++] = NUM_VERTICES + 5;

						break;

					case 1:// diag: 1-3
						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 1;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 3;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 1;	inds[fi++] = NUM_VERTICES + 4;
						inds[fi++] = NUM_VERTICES + 5;	inds[fi++] = NUM_VERTICES + 3;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 5;
						inds[fi++] = NUM_VERTICES + 3;	inds[fi++] = NUM_VERTICES + 1;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 3;
						inds[fi++] = NUM_VERTICES + 4;	inds[fi++] = NUM_VERTICES + 1;

						break;

					case 2:// diag 2-4
						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 2;
						inds[fi++] = NUM_VERTICES + 3;	inds[fi++] = NUM_VERTICES + 4;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 1;	inds[fi++] = NUM_VERTICES + 2;
						inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 4;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 3;
						inds[fi++] = NUM_VERTICES + 4;	inds[fi++] = NUM_VERTICES + 5;

						inds[fi++] = GOID_TETRAHEDRON;
						inds[fi++] = NUM_VERTICES + 4;	inds[fi++] = NUM_VERTICES + 1;
						inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 5;

						break;
					}
				}break;
				
				case HYBRID_TET_OCT:
				{
				//	REGULAR REFINEMENT
					int& fi = fillCount;
					int* inds = newIndsOut;

				//	outer tetrahedrons analogously defined to STANDARD case
					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 0;					inds[fi++] = NUM_VERTICES + 0;
					inds[fi++] = NUM_VERTICES + 2;	inds[fi++] = NUM_VERTICES + 3;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 1;					inds[fi++] = NUM_VERTICES + 1;
					inds[fi++] = NUM_VERTICES + 0;	inds[fi++] = NUM_VERTICES + 4;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = 2;					inds[fi++] = NUM_VERTICES + 2;
					inds[fi++] = NUM_VERTICES + 1;	inds[fi++] = NUM_VERTICES + 5;

					inds[fi++] = GOID_TETRAHEDRON;
					inds[fi++] = NUM_VERTICES + 3;	inds[fi++] = NUM_VERTICES + 4;
					inds[fi++] = NUM_VERTICES + 5;	inds[fi++] = 3;

				//	inner octahedron:
				//	For the remaining inner cavity we'll choose the shortest diagonal
				//	and order the octahedral nodes, so that, the implicit
				//	subdivision of the octahedron into tetrahedrons during
				//	discretization happens alongside exactly this shortest diagonal.
					int bestDiag = 2;
					if(corners){
					//	there are three diagonals between the following edge-centers:
					//	0-5, 1-3, 2-4
						vector3 c1, c2;

					//	0-5
						VecAdd(c1, corners[0], corners[1]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[2], corners[3]);
						VecScale(c2, c2, 0.5);
						number d05 = VecDistanceSq(c1, c2);

					//	1-3
						VecAdd(c1, corners[1], corners[2]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[0], corners[3]);
						VecScale(c2, c2, 0.5);
						number d13 = VecDistanceSq(c1, c2);

					//	2-4
						VecAdd(c1, corners[0], corners[2]);
						VecScale(c1, c1, 0.5);
						VecAdd(c2, corners[1], corners[3]);
						VecScale(c2, c2, 0.5);
						number d = VecDistanceSq(c1, c2);

						if(d13 < d){
							bestDiag = 1;
							d = d13;
						}
						if(d05 < d){
							bestDiag = 0;
						}
					}

					switch(bestDiag){
						case 0:// diag: 0-5
							inds[fi++] = GOID_OCTAHEDRON;
							inds[fi++] = NUM_VERTICES + 1;		inds[fi++] = NUM_VERTICES + 0;
							inds[fi++] = NUM_VERTICES + 4;		inds[fi++] = NUM_VERTICES + 5;
							inds[fi++] = NUM_VERTICES + 2;		inds[fi++] = NUM_VERTICES + 3;
						break;

						case 1:// diag: 1-3
							inds[fi++] = GOID_OCTAHEDRON;
							inds[fi++] = NUM_VERTICES + 0;		inds[fi++] = NUM_VERTICES + 3;
							inds[fi++] = NUM_VERTICES + 4;		inds[fi++] = NUM_VERTICES + 1;
							inds[fi++] = NUM_VERTICES + 2;		inds[fi++] = NUM_VERTICES + 5;
						break;

						case 2:// diag 2-4
							inds[fi++] = GOID_OCTAHEDRON;
							inds[fi++] = NUM_VERTICES + 1;		inds[fi++] = NUM_VERTICES + 2;
							inds[fi++] = NUM_VERTICES + 0;		inds[fi++] = NUM_VERTICES + 4;
							inds[fi++] = NUM_VERTICES + 5;		inds[fi++] = NUM_VERTICES + 3;
						break;
					}break;

				}break;
			}
		}break;
	}

	if(fillCount == 0){
	//	call recursive refine
		fillCount = shared_rules::RecursiveRefine(newIndsOut, newEdgeVrts,
									FACE_VRT_INDS, FACE_EDGE_INDS, NUM_VERTICES,
									NUM_EDGES, NUM_FACES);

	//	the rule requires a new center vertex
		newCenterOut = true;
	}

	return fillCount;
}
Example #27
0
/*************
 * DESCRIPTION: -
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParseNamedObject(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK     chunk;
	TRIANGLE *triangle;
	TRILIST  *ph1,*ph2;
	float     angle;
	UWORD     p1, p2, p3;
	UWORD     *edges;
	int       i, h;

	ReadASCIIZ(data, data->ObjName);
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_TRIANGLE:
				ParseTriObject(data, &chunk);
				break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);

	if (data->TriList && (data->link->type == LINK_RENDERER))
	{
		// go through all vertices and calculate normals (only for renderer)
		for (i = 0; i < data->pointcount; i++)
		{
			data->VertNorms[i].x = data->VertNorms[i].y = data->VertNorms[i].z = 0.f;
			ph1 = data->TriList[i];
			while (ph1)
			{
				for (ph2 = ph1->next; ph2 != NULL; ph2 = ph2->next)
				{
					if (!ph1->flag || !ph2->flag)
					{
						// test angle between two triangles
						angle = VecAngle(data->TriNorms[ph1->tri], data->TriNorms[ph2->tri]);
//                if (angle < 2*PI && angle > /*cos_*/smooth_angle)
						if (angle >0 && angle < /*cos_*/data->smooth_angle)
						{
							if (!ph1->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph1->tri], &data->VertNorms[i]);
								ph1->flag = TRUE;
								data->TriSmooth[ph1->tri] = TRUE;
							}
							if (!ph2->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph2->tri], &data->VertNorms[i]);
								ph2->flag = TRUE;
								data->TriSmooth[ph2->tri] = TRUE;
							}
						}
					}
				}
				ph2 = ph1;
				ph1 = ph1->next;
				delete ph2;
			}
			VecNormalize(&data->VertNorms[i]);
		}
	}

	if (data->face)
	{
		data->link->ObjectBegin(data->rc);

		data->defaultsurface = data->link->SurfaceAdd(data->rc);
		if (!data->defaultsurface)
		{
			data->err = ERR_MEM;
			return;
		}

		data->link->SurfaceName(data->rc, data->defaultsurface, "default");
		data->link->SurfaceDiffuse(data->rc, data->defaultsurface, 0.9f, 0.9f, 0.9f);
		data->link->SurfaceAmbient(data->rc, data->defaultsurface, 0.1f, 0.1f, 0.1f);
		data->link->SurfaceRefPhong(data->rc, data->defaultsurface, 49.f);

		triangle = data->link->TriangleAdd(data->rc, data->facecount,data->defaultsurface,data->mainactor);
		if (!triangle)
		{
			data->err = ERR_MEM;
			return;
		}
		if (data->link->type == LINK_SCENARIO)
		{  // modeler needs points,edges and faces seperate
			if (data->link->TriangleAddPoints(data->rc, data->pointcount,data->points) == -1)
			{
				data->err = ERR_MEM;
				return;
			}
			edges = new UWORD[data->facecount*6];
			if (!edges)
			{
				data->err = ERR_MEM;
				return;
			}
			for (i = 0; i < data->facecount; i++)
			{
				h = i*6;
				edges[h++] = data->face[i].p1;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p1;
			}
			if (data->link->TriangleAddEdges(data->rc, data->facecount*3,edges) == -1)
			{
				delete edges;
				data->err = ERR_MEM;
				return;
			}
			delete edges;
		}
		for (i = 0; i < data->facecount; i++)
		{
			p1 = data->face[i].p1;
			p2 = data->face[i].p3;
			p3 = data->face[i].p2;

			if(data->replacesurface)
				data->link->TriangleSurface(data->rc, triangle, data->replacesurface);
			else
			{
				if(!data->material[i])
					data->link->TriangleSurface(data->rc, triangle, data->defaultsurface);
				else
					data->link->TriangleSurface(data->rc, triangle, data->material[i]);
			}

			if (data->link->type == LINK_SCENARIO)
			{  // modeler needs edges
				data->link->TriangleSetEdges(data->rc, triangle,i*3,i*3+1,i*3+2);
			}
			else
			{
				// raystorm renderer needs triangles and normals
				data->link->TrianglePoints(data->rc, triangle,&data->points[p1],&data->points[p2],&data->points[p3]);

				if (!VecZero(data->TriNorms[i]))
				{
					// generate smooth triangle when smooth flag is set
					if (data->TriSmooth[i])
					{
						data->link->TriangleVNorm(data->rc, triangle,
							VecZero(data->VertNorms[p1]) ? &data->TriNorms[i] : &data->VertNorms[p1],
							VecZero(data->VertNorms[p2]) ? &data->TriNorms[i] : &data->VertNorms[p2],
							VecZero(data->VertNorms[p3]) ? &data->TriNorms[i] : &data->VertNorms[p3]);
					}
				}
				if(data->mapping)
				{
					data->link->TriangleUV(data->rc, triangle,
						&data->mapping[p1], &data->mapping[p2], &data->mapping[p3]);
				}
			}

			// next triangle
			triangle = data->link->TriangleGetNext(data->rc, triangle);
		}
		data->link->ObjectEnd(data->rc);
	}

	CleanupMesh(data);
}
Example #28
0
/*************
 * DESCRIPTION:   generate normal for one triangle point
 * INPUT:         tnum     current triangle index
 *                n        calculated normal
 *                normals  flat normal array
 *                edgidx   index array which points to two triangles for each edge
 *                p        point to generate normal of
 *                edges    edge array
 *                trias    triangle array
 * OUTPUT:        -
 *************/
static void GenerateNormal(UWORD tnum, VECTOR *n, VECTOR *normals, UWORD *edgidx, UWORD p, EDGE *edges, MESH *trias)
{
	UWORD e[2], edge, edge2, oldtria;
	int j, i;
	MESH *tria, *t;

	tria = &trias[tnum];

	j = 0;
	if((p == edges[tria->e[0]].p[0]) || (p == edges[tria->e[0]].p[1]))
		e[j++] = tria->e[0];
	if((p == edges[tria->e[1]].p[0]) || (p == edges[tria->e[1]].p[1]))
		e[j++] = tria->e[1];

	if((p == edges[tria->e[2]].p[0]) || (p == edges[tria->e[2]].p[1]))
	{
		// degenerated triangle ?
		if(j==2)
			return;
		e[j++] = tria->e[2];
	}

	for(j=0; j<2; j++)
	{
		edge = e[j];
		oldtria = tnum;
		i = 0;
		while(!(edges[edge].flags & EDGE_SHARP) && i<50)
		{
			// get next triangle with same edge
			edge2 = edge*2;
			if(oldtria != edgidx[edge2])
			{
				oldtria = edgidx[edge2];
				t = &trias[oldtria];
			}
			else
			{
				oldtria = edgidx[edge2+1];
				if(oldtria == 0xffff)
					break;
				t = &trias[oldtria];
			}

			if(t == tria)
			{
				// avoid endless loops
				break;
			}

			// add normal
			if(dotp(n, &normals[oldtria]) < 0.f)
				VecSub(n, &normals[oldtria], n);
			else
				VecAdd(n, &normals[oldtria], n);

			// get new edge
			if((edge != t->e[0]) && ((p == edges[t->e[0]].p[0]) || (p == edges[t->e[0]].p[1])))
				edge = t->e[0];
			else
			{
				if((edge != t->e[1]) && ((p == edges[t->e[1]].p[0]) || (p == edges[t->e[1]].p[1])))
					 edge = t->e[1];
				else
				{
					 if((edge != t->e[2]) && ((p == edges[t->e[2]].p[0]) || (p == edges[t->e[2]].p[1])))
						 edge = t->e[2];
				}
			}
			// continue the search with the new edge

			i++;
		}
	}
	// Normalize
	VecNormalize(n);
}