Exemple #1
0
// Neutral case: returns whether vertex-source data was used (present in animated models)
bool Model3D::FindPositions_Neutral(bool UseModelTransform)
{
  // Positions already there
  if (VtxSrcIndices.empty()) {
    return false;
  }

  // Straight copy of the vertices:

  size_t NumVertices = VtxSrcIndices.size();
  Positions.resize(3*NumVertices);

  GLfloat *PP = PosBase();
  GLushort *IP = VtxSIBase();

  size_t NumVtxSources = VtxSources.size();

  if (UseModelTransform) {
    for (size_t k=0; k<NumVertices; k++, IP++, PP+=3)
    {
      size_t VSIndex = *IP;
      if (VSIndex >= 0 && VSIndex < NumVtxSources) {
        Model3D_VertexSource& VS = VtxSources[VSIndex];
        TransformPoint(PP,VS.Position,TransformPos);
      }
      else
      {
        GLfloat VP[3] = {0,0,0};
        TransformPoint(PP,VP,TransformPos);
      }
    }
  }
  else
  {
    for (size_t k=0; k<NumVertices; k++, IP++)
    {
      size_t VSIndex = *IP;
      if (VSIndex >= 0 && VSIndex < NumVtxSources) {
        Model3D_VertexSource& VS = VtxSources[VSIndex];
        GLfloat *VP = VS.Position;
        *(PP++) = *(VP++);
        *(PP++) = *(VP++);
        *(PP++) = *(VP++);
      }
      else
      {
        *(PP++) = 0;
        *(PP++) = 0;
        *(PP++) = 0;
      }
    }
  }

  // Copy in the normals
  Normals.resize(NormSources.size());

  if (UseModelTransform) {
    GLfloat *NormPtr = NormBase();
    GLfloat *NormBasePtr = NormSrcBase();
    size_t NumNorms = NormSources.size()/3;
    for (size_t k=0; k<NumNorms; k++, NormPtr+=3, NormBasePtr+=3)
    {
      TransformVector(NormPtr, NormBasePtr, TransformNorm);
    }
  }
  else
  {
    objlist_copy(NormBase(),NormSrcBase(),NormSources.size());
  }

  return true;
}
Exemple #2
0
/*
================
R_EmitEdge
================
*/
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) {
	edge_t *edge, *pcheck;
	int u_check, v, v2, ceilv0, side;
	float u, u_step, *world, scale, lzi0, u0, v0;
	vec3_t local, transformed;

	if (r_lastvertvalid) {
		u0 = r_u1;
		v0 = r_v1;
		lzi0 = r_lzi1;
		ceilv0 = r_ceilv1;
	} else {
		world = &pv0->position[0];
	
		// transform and project
		VectorSubtract (world, modelorg, local);
		TransformVector (local, transformed);
	
		if (transformed[2] < NEAR_CLIP)
			transformed[2] = NEAR_CLIP;
	
		lzi0 = 1.0 / transformed[2];
	
		// FIXME: build x/yscale into transform?
		scale = xscale * lzi0;
		u0 = (xcenter + scale * transformed[0]);
		u0 = bound(r_refdef.fvrectx_adj, u0, r_refdef.fvrectright_adj);
	
		scale = yscale * lzi0;
		v0 = (ycenter - scale * transformed[1]);
		v0 = bound(r_refdef.fvrecty_adj, v0, r_refdef.fvrectbottom_adj);
	
		ceilv0 = (int) ceil(v0);
	}

	world = &pv1->position[0];

	// transform and project
	VectorSubtract (world, modelorg, local);
	TransformVector (local, transformed);

	if (transformed[2] < NEAR_CLIP)
		transformed[2] = NEAR_CLIP;

	r_lzi1 = 1.0 / transformed[2];

	scale = xscale * r_lzi1;
	r_u1 = (xcenter + scale * transformed[0]);
	r_u1 = bound(r_refdef.fvrectx_adj, r_u1, r_refdef.fvrectright_adj);

	scale = yscale * r_lzi1;
	r_v1 = (ycenter - scale * transformed[1]);
	r_v1 = bound(r_refdef.fvrecty_adj, r_v1, r_refdef.fvrectbottom_adj);

	if (r_lzi1 > lzi0)
		lzi0 = r_lzi1;

	if (lzi0 > r_nearzi)	// for mipmap finding
		r_nearzi = lzi0;

	// for right edges, all we want is the effect on 1/z
	if (r_nearzionly)
		return;

	r_emitted = 1;

	r_ceilv1 = (int) ceil(r_v1);


	// create the edge
	if (ceilv0 == r_ceilv1) {
		// we cache unclipped horizontal edges as fully clipped
		if (cacheoffset != 0x7FFFFFFF)
			cacheoffset = FULLY_CLIPPED_CACHED |(r_framecount & FRAMECOUNT_MASK);
		return;		// horizontal edge
	}

	side = ceilv0 > r_ceilv1;

	edge = edge_p++;

	edge->owner = r_pedge;

	edge->nearzi = lzi0;

	if (side == 0) {
		// trailing edge (go from p1 to p2)
		v = ceilv0;
		v2 = r_ceilv1 - 1;

		edge->surfs[0] = surface_p - surfaces;
		edge->surfs[1] = 0;

		u_step = ((r_u1 - u0) / (r_v1 - v0));
		u = u0 + ((float)v - v0) * u_step;
	} else {
		// leading edge (go from p2 to p1)
		v2 = ceilv0 - 1;
		v = r_ceilv1;

		edge->surfs[0] = 0;
		edge->surfs[1] = surface_p - surfaces;

		u_step = ((u0 - r_u1) / (v0 - r_v1));
		u = r_u1 + ((float)v - r_v1) * u_step;
	}

	edge->u_step = u_step*0x100000;
	edge->u = u*0x100000 + 0xFFFFF;

	// we need to do this to avoid stepping off the edges if a very nearly horizontal edge is less
	// than epsilon above a scan, and numeric error causes it to incorrectly extend to the scan,
	// and the extension of the line goes off the edge of the screen
	// FIXME: is this actually needed?
	if (edge->u < r_refdef.vrect_x_adj_shift20)
		edge->u = r_refdef.vrect_x_adj_shift20;
	if (edge->u > r_refdef.vrectright_adj_shift20)
		edge->u = r_refdef.vrectright_adj_shift20;

	// sort the edge in normally
	u_check = edge->u;
	if (edge->surfs[0])
		u_check++;	// sort trailers after leaders

	if (!newedges[v] || newedges[v]->u >= u_check) {
		edge->next = newedges[v];
		newedges[v] = edge;
	} else {
		pcheck = newedges[v];
		while (pcheck->next && pcheck->next->u < u_check)
			pcheck = pcheck->next;
		edge->next = pcheck->next;
		pcheck->next = edge;
	}

	edge->nextremove = removeedges[v2];
	removeedges[v2] = edge;
}
void R_SetupAndDrawSprite (void) {
    int i, nump;
    float dot, scale, *pv;
    vec5_t *pverts;
    vec3_t left, up, right, down, transformed, local;
    emitpoint_t	outverts[MAXWORKINGVERTS + 1], *pout;

    dot = DotProduct (r_spritedesc.vpn, modelorg);

    // backface cull
    if (dot >= 0)
        return;

    // build the sprite poster in worldspace
    VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right);
    VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up);
    VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left);
    VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down);

    pverts = clip_verts[0];

    pverts[0][0] = r_entorigin[0] + up[0] + left[0];
    pverts[0][1] = r_entorigin[1] + up[1] + left[1];
    pverts[0][2] = r_entorigin[2] + up[2] + left[2];
    pverts[0][3] = 0;
    pverts[0][4] = 0;

    pverts[1][0] = r_entorigin[0] + up[0] + right[0];
    pverts[1][1] = r_entorigin[1] + up[1] + right[1];
    pverts[1][2] = r_entorigin[2] + up[2] + right[2];
    pverts[1][3] = sprite_width;
    pverts[1][4] = 0;

    pverts[2][0] = r_entorigin[0] + down[0] + right[0];
    pverts[2][1] = r_entorigin[1] + down[1] + right[1];
    pverts[2][2] = r_entorigin[2] + down[2] + right[2];
    pverts[2][3] = sprite_width;
    pverts[2][4] = sprite_height;

    pverts[3][0] = r_entorigin[0] + down[0] + left[0];
    pverts[3][1] = r_entorigin[1] + down[1] + left[1];
    pverts[3][2] = r_entorigin[2] + down[2] + left[2];
    pverts[3][3] = 0;
    pverts[3][4] = sprite_height;

    // clip to the frustum in worldspace
    nump = 4;
    clip_current = 0;

    for (i = 0; i < 4; i++)
    {
        nump = R_ClipSpriteFace (nump, &view_clipplanes[i]);
        if (nump < 3)
            return;
        if (nump >= MAXWORKINGVERTS)
            Host_Error ("R_SetupAndDrawSprite: too many points");
    }

    // transform vertices into viewspace and project
    pv = &clip_verts[clip_current][0][0];
    r_spritedesc.nearzi = -999999;

    for (i = 0; i < nump; i++) {
        VectorSubtract (pv, r_origin, local);
        TransformVector (local, transformed);

        if (transformed[2] < NEAR_CLIP)
            transformed[2] = NEAR_CLIP;

        pout = &outverts[i];
        pout->zi = 1.0 / transformed[2];
        if (pout->zi > r_spritedesc.nearzi)
            r_spritedesc.nearzi = pout->zi;

        pout->s = pv[3];
        pout->t = pv[4];

        scale = xscale * pout->zi;
        pout->u = (xcenter + scale * transformed[0]);

        scale = yscale * pout->zi;
        pout->v = (ycenter - scale * transformed[1]);

        pv += sizeof (vec5_t) / sizeof (*pv);
    }

    // draw it
    r_spritedesc.nump = nump;
    r_spritedesc.pverts = outverts;
    D_DrawSprite ();
}
Exemple #4
0
void R_RenderFace (msurface_t *fa, int clipflags) {
	int i, lindex;
	unsigned mask;
	mplane_t *pplane;
	float distinv;
	vec3_t p_normal;
	medge_t *pedges, tedge;
	clipplane_t *pclip;

	// skip out if no more surfs
	if (surface_p >= surf_max) {
		r_outofsurfaces++;
		return;
	}

	// ditto if not enough edges left, or switch to auxedges if possible
	if ((edge_p + fa->numedges + 4) >= edge_max) {
		r_outofedges += fa->numedges;
		return;
	}

	c_faceclip++;

	// set up clip planes
	pclip = NULL;

	for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1) {
		if (clipflags & mask) {
			view_clipplanes[i].next = pclip;
			pclip = &view_clipplanes[i];
		}
	}

	// push the edges through
	r_emitted = 0;
	r_nearzi = 0;
	r_nearzionly = false;
	makeleftedge = makerightedge = false;
	pedges = currententity->model->edges;
	r_lastvertvalid = false;

	for (i = 0; i < fa->numedges; i++) {
		lindex = currententity->model->surfedges[fa->firstedge + i];

		if (lindex > 0) {
			r_pedge = &pedges[lindex];

			// if the edge is cached, we can just reuse the edge
			if (!insubmodel) {
				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) {
					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == r_framecount) {
						r_lastvertvalid = false;
						continue;
					}
				} else {
					if ((((unsigned long)edge_p - (unsigned long)r_edges) > r_pedge->cachededgeoffset) &&
						(((edge_t *)((unsigned long) r_edges + r_pedge->cachededgeoffset))->owner == r_pedge))
					{
						R_EmitCachedEdge ();
						r_lastvertvalid = false;
						continue;
					}
				}
			}

			// assume it's cacheable
			cacheoffset = (byte *)edge_p - (byte *)r_edges;
			r_leftclipped = r_rightclipped = false;
			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], &r_pcurrentvertbase[r_pedge->v[1]], pclip);
			r_pedge->cachededgeoffset = cacheoffset;

			if (r_leftclipped)
				makeleftedge = true;
			if (r_rightclipped)
				makerightedge = true;
			r_lastvertvalid = true;
		} else {
			lindex = -lindex;
			r_pedge = &pedges[lindex];
			// if the edge is cached, we can just reuse the edge
			if (!insubmodel) {
				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) {
					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == r_framecount) {
						r_lastvertvalid = false;
						continue;
					}
				} else {
					// it's cached if the cached edge is valid and is owned by this medge_t
					if ((((unsigned long)edge_p - (unsigned long)r_edges) > r_pedge->cachededgeoffset) &&
						(((edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset))->owner == r_pedge))
					{
						R_EmitCachedEdge ();
						r_lastvertvalid = false;
						continue;
					}
				}
			}

			// assume it's cacheable
			cacheoffset = (byte *)edge_p - (byte *)r_edges;
			r_leftclipped = r_rightclipped = false;
			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], &r_pcurrentvertbase[r_pedge->v[0]], pclip);
			r_pedge->cachededgeoffset = cacheoffset;

			if (r_leftclipped)
				makeleftedge = true;
			if (r_rightclipped)
				makerightedge = true;
			r_lastvertvalid = true;
		}
	}

	// if there was a clip off the left edge, add that edge too
	// FIXME: faster to do in screen space?
	// FIXME: share clipped edges?
	if (makeleftedge) {
		r_pedge = &tedge;
		r_lastvertvalid = false;
		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
	}

	// if there was a clip off the right edge, get the right r_nearzi
	if (makerightedge) {
		r_pedge = &tedge;
		r_lastvertvalid = false;
		r_nearzionly = true;
		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
	}

	// if no edges made it out, return without posting the surface
	if (!r_emitted)
		return;

	r_polycount++;

	surface_p->data = (void *)fa;
	surface_p->nearzi = r_nearzi;
	surface_p->flags = fa->flags;
	surface_p->insubmodel = insubmodel;
	surface_p->spanstate = 0;
	surface_p->entity = currententity;
	surface_p->key = r_currentkey++;
	surface_p->spans = NULL;

	pplane = fa->plane;
	// FIXME: cache this?
	TransformVector (pplane->normal, p_normal);
	// FIXME: cache this?
	distinv = 1.0 / (-PlaneDiff(modelorg, pplane));

	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
	surface_p->d_ziorigin = p_normal[2] * distinv - xcenter * surface_p->d_zistepu - ycenter * surface_p->d_zistepv;

	surface_p++;
}
Exemple #5
0
void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) {
	int i;
	unsigned mask;
	mplane_t *pplane;
	float distinv;
	vec3_t p_normal;
	medge_t tedge;
	clipplane_t	*pclip;

	// skip out if no more surfs
	if (surface_p >= surf_max) {
		r_outofsurfaces++;
		return;
	}

	// ditto if not enough edges left, or switch to auxedges if possible
	if ((edge_p + psurf->numedges + 4) >= edge_max) {
		r_outofedges += psurf->numedges;
		return;
	}

	c_faceclip++;

	// this is a dummy to give the caching mechanism someplace to write to
	r_pedge = &tedge;

	// set up clip planes
	pclip = NULL;

	for (i = 3, mask = 0x08 ; i >= 0 ; i--, mask >>= 1) {
		if (r_clipflags & mask) {
			view_clipplanes[i].next = pclip;
			pclip = &view_clipplanes[i];
		}
	}

	// push the edges through
	r_emitted = 0;
	r_nearzi = 0;
	r_nearzionly = false;
	makeleftedge = makerightedge = false;
	// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching can be used?
	r_lastvertvalid = false;

	for ( ; pedges ; pedges = pedges->pnext) {
		r_leftclipped = r_rightclipped = false;
		R_ClipEdge (pedges->v[0], pedges->v[1], pclip);

		if (r_leftclipped)
			makeleftedge = true;
		if (r_rightclipped)
			makerightedge = true;
	}

	// if there was a clip off the left edge, add that edge too
	// FIXME: faster to do in screen space?
	// FIXME: share clipped edges?
	if (makeleftedge) {
		r_pedge = &tedge;
		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
	}

	// if there was a clip off the right edge, get the right r_nearzi
	if (makerightedge) {
		r_pedge = &tedge;
		r_nearzionly = true;
		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
	}

	// if no edges made it out, return without posting the surface
	if (!r_emitted)
		return;

	r_polycount++;

	surface_p->data = (void *)psurf;
	surface_p->nearzi = r_nearzi;
	surface_p->flags = psurf->flags;
	surface_p->insubmodel = true;
	surface_p->spanstate = 0;
	surface_p->entity = currententity;
	surface_p->key = r_currentbkey;
	surface_p->spans = NULL;

	pplane = psurf->plane;
	// FIXME: cache this?
	TransformVector (pplane->normal, p_normal);
	// FIXME: cache this?
	distinv = 1.0 / (-PlaneDiff(modelorg, pplane));

	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
	surface_p->d_ziorigin = p_normal[2] * distinv - xcenter * surface_p->d_zistepu - ycenter * surface_p->d_zistepv;

	surface_p++;
}
int32 FSlateTextLayout::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
{
	const FSlateRect ClippingRect = AllottedGeometry.GetClippingRect().IntersectionWith(MyClippingRect);
	const ESlateDrawEffect::Type DrawEffects = bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect;

	static bool ShowDebug = false;
	FLinearColor BlockHue( 0, 1.0f, 1.0f, 0.5 );
	int32 HighestLayerId = LayerId;

	for (const FTextLayout::FLineView& LineView : LineViews)
	{
		// Is this line visible?
		const FSlateRect LineViewRect(AllottedGeometry.AbsolutePosition + LineView.Offset, AllottedGeometry.AbsolutePosition + LineView.Offset + LineView.Size);
		const FSlateRect VisibleLineView = ClippingRect.IntersectionWith(LineViewRect);
		if (VisibleLineView.IsEmpty())
		{
			continue;
		}

		// Render any underlays for this line
		const int32 HighestUnderlayLayerId = OnPaintHighlights( Args, LineView, LineView.UnderlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled );

		const int32 BlockDebugLayer = HighestUnderlayLayerId;
		const int32 TextLayer = BlockDebugLayer + 1;
		int32 HighestBlockLayerId = TextLayer;

		// Render every block for this line
		for (const TSharedRef< ILayoutBlock >& Block : LineView.Blocks)
		{
			if ( ShowDebug )
			{
				BlockHue.R += 50.0f;

				// The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry
				const float InverseScale = Inverse(AllottedGeometry.Scale);

				FSlateDrawElement::MakeBox(
					OutDrawElements, 
					BlockDebugLayer,
					AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))),
					&DefaultTextStyle.HighlightShape,
					ClippingRect,
					DrawEffects,
					InWidgetStyle.GetColorAndOpacityTint() * BlockHue.HSVToLinearRGB()
					);
			}

			const TSharedRef< ISlateRun > Run = StaticCastSharedRef< ISlateRun >( Block->GetRun() );

			int32 HighestRunLayerId = TextLayer;
			const TSharedPtr< ISlateRunRenderer > RunRenderer = StaticCastSharedPtr< ISlateRunRenderer >( Block->GetRenderer() );
			if ( RunRenderer.IsValid() )
			{
				HighestRunLayerId = RunRenderer->OnPaint( Args, LineView, Run, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled );
			}
			else
			{
				HighestRunLayerId = Run->OnPaint( Args, LineView, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled );
			}

			HighestBlockLayerId = FMath::Max( HighestBlockLayerId, HighestRunLayerId );
		}

		// Render any overlays for this line
		const int32 HighestOverlayLayerId = OnPaintHighlights( Args, LineView, LineView.OverlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, HighestBlockLayerId, InWidgetStyle, bParentEnabled );
		HighestLayerId = FMath::Max( HighestLayerId, HighestOverlayLayerId );
	}

	return HighestLayerId;
}
Exemple #7
0
/***********************************************************************

  ComputeInitLink() - this function computes the initial end points, 
		u,v,n vectors, and rotation matrix for the specified link.

  for the given link
	set visible end to origin + vislen
	set actual end to origin + totlen
	rotate both points by theta about z axis
	translate both points to actual end of previous link
	compute u,v,n vectors
	map end points to screen coordinates

***********************************************************************/
int 
ComputeInitLink(int link, MyProgram *data)
{
   vectorType	o2, o2prime, o3, o3prime;
   vectorType	p1, p2, p3;
   vectorType	u, v, vprime, n;

   double	world[4];
   double	screen[4];

   matrixType 	translation;
   matrixType	rotation;
   matrixType	screen_map;

   pointType MapWPointToScreen(wpointType *p, matrixType *map);


   /*  set actual end to origin + totlen
    */
   o3.x = data->links[link].total_length;
   o3.y = 0.0;
   o3.z = 0.0;

   /* set visible end to origin + vislen
    */
   o2.x = data->links[link].visible_length;
   o2.y = 0.0;
   o2.z = 0.0;

   /*  make rotation matrix
    */
   rotation = MakeRotationMatrix('z', data->links[link].zrot_deg);

   MatrixCopy(&rotation, &data->links[link].rot_mat);

   /*  rotate actual and visible end points around z axis
    */
   o3prime = TransformVector(&o3, &rotation);    /* o3prime = o3 * Rz(theta) */
   o2prime = TransformVector(&o2, &rotation);    /* o2prime = o2 * Rz(theta) */

   /*  set start of link to actual end of previous link if not root link 
    */
   if (data->links[link].type == LINK_ROOT) {	/* root link */
      p1.x = data->links[link].w_start.x;
      p1.y = data->links[link].w_start.y;
      p1.z = data->links[link].w_start.z;
   }
   else {					/* normal link */
      p1.x = data->links[link - 1].w_end.x;
      p1.y = data->links[link - 1].w_end.y;
      p1.z = data->links[link - 1].w_end.z;
   }

   /*  make translation matrix
    */
   translation = MakeTranslationMatrix(p1.x, p1.y, p1.z);

   /*  translate actual end and visible end to final locations
    */
   p3 = TransformVector(&o3prime, &translation); /* p3 = o3prime * T(ox,oy,oz) */
   p2 = TransformVector(&o2prime, &translation); /* p2 = o2prime * T(ox,oy,oz) */

   /*  copy final end locations to link data
    */
   data->links[link].w_end.x = p3.x;		/* actual end */
   data->links[link].w_end.y = p3.y;
   data->links[link].w_end.z = p3.z;
   data->links[link].w_visend.x = p2.x;		/* visible end */
   data->links[link].w_visend.y = p2.y;
   data->links[link].w_visend.z = p2.z;
   data->links[link].w_start.x = p1.x;		/* start point */
   data->links[link].w_start.y = p1.y;
   data->links[link].w_start.z = p1.z;

   /*  compute u vector
    */
   u = VecSub(&p1, &p3);		/* u = p3 - p1 */
   VecNormalize(&u);			/* u = u / mag(u) */

   /*  compute n vector 
    */
   vprime.x = 0.0;
   vprime.y = 1.0;
   vprime.z = 0.0;
   n = VecCrossproduct(&u, &vprime);	/* n = u X vprime */

   /*  compute v vector
    */
   v = VecCrossproduct(&n, &u);		/* v = n X u */

   /*  copy u,v,n vectors to link data
    */
   data->links[link].u_vec.x = u.x;
   data->links[link].u_vec.y = u.y;
   data->links[link].u_vec.z = u.z;

   data->links[link].v_vec.x = v.x;
   data->links[link].v_vec.y = v.y;
   data->links[link].v_vec.z = v.z;

   data->links[link].n_vec.x = n.x;
   data->links[link].n_vec.y = n.y;
   data->links[link].n_vec.z = n.z;

   /*  map start and end points to screen coordinates
    */
   world[0] = WB_MINX;
   world[1] = WB_MINY;
   world[2] = WB_MAXX;
   world[3] = WB_MAXY;
   screen[0] = 0.0;
   screen[1] = 0.0;
   screen[2] = SCREEN_X_SIZE;
   screen[3] = SCREEN_Y_SIZE;
   screen_map = MakeMappingMatrix(world, screen);

   data->links[link].start = MapWPointToScreen( &data->links[link].w_start, &screen_map);
   data->links[link].end = MapWPointToScreen( &data->links[link].w_end, &screen_map);
   data->links[link].visend = MapWPointToScreen( &data->links[link].w_visend, &screen_map);


#ifdef INVKINE_DEBUG
   OutputLink(stdout, data, link);
#endif

   return(0);
} /* end of ComputeInitLink() */
Exemple #8
0
/*
================
R_RenderPoly
================
*/
void
R_RenderPoly(msurface_t *fa, int clipflags)
{
    int i, lindex, lnumverts, s_axis, t_axis;
    float dist, lastdist, lzi, scale, u, v, frac;
    unsigned mask;
    vec3_t local, transformed;
    clipplane_t *pclip;
    medge_t *pedges;
    mplane_t *pplane;
    mvertex_t verts[2][100];	//FIXME: do real number
    polyvert_t pverts[100];	//FIXME: do real number, safely
    int vertpage, newverts, newpage, lastvert;
    qboolean visible;

// FIXME: clean this up and make it faster
// FIXME: guard against running out of vertices

    s_axis = t_axis = 0;	// keep compiler happy

// set up clip planes
    pclip = NULL;

    for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1) {
	if (clipflags & mask) {
	    view_clipplanes[i].next = pclip;
	    pclip = &view_clipplanes[i];
	}
    }

// reconstruct the polygon
// FIXME: these should be precalculated and loaded off disk
    pedges = currententity->model->edges;
    lnumverts = fa->numedges;
    vertpage = 0;

    for (i = 0; i < lnumverts; i++) {
	lindex = currententity->model->surfedges[fa->firstedge + i];

	if (lindex > 0) {
	    r_pedge = &pedges[lindex];
	    verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]];
	} else {
	    r_pedge = &pedges[-lindex];
	    verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]];
	}
    }

// clip the polygon, done if not visible
    while (pclip) {
	lastvert = lnumverts - 1;
	lastdist = DotProduct(verts[vertpage][lastvert].position,
			      pclip->normal) - pclip->dist;

	visible = false;
	newverts = 0;
	newpage = vertpage ^ 1;

	for (i = 0; i < lnumverts; i++) {
	    dist = DotProduct(verts[vertpage][i].position, pclip->normal) -
		pclip->dist;

	    if ((lastdist > 0) != (dist > 0)) {
		frac = dist / (dist - lastdist);
		verts[newpage][newverts].position[0] =
		    verts[vertpage][i].position[0] +
		    ((verts[vertpage][lastvert].position[0] -
		      verts[vertpage][i].position[0]) * frac);
		verts[newpage][newverts].position[1] =
		    verts[vertpage][i].position[1] +
		    ((verts[vertpage][lastvert].position[1] -
		      verts[vertpage][i].position[1]) * frac);
		verts[newpage][newverts].position[2] =
		    verts[vertpage][i].position[2] +
		    ((verts[vertpage][lastvert].position[2] -
		      verts[vertpage][i].position[2]) * frac);
		newverts++;
	    }

	    if (dist >= 0) {
		verts[newpage][newverts] = verts[vertpage][i];
		newverts++;
		visible = true;
	    }

	    lastvert = i;
	    lastdist = dist;
	}

	if (!visible || (newverts < 3))
	    return;

	lnumverts = newverts;
	vertpage ^= 1;
	pclip = pclip->next;
    }

// transform and project, remembering the z values at the vertices and
// r_nearzi, and extract the s and t coordinates at the vertices
    pplane = fa->plane;
    switch (pplane->type) {
    case PLANE_X:
    case PLANE_ANYX:
	s_axis = 1;
	t_axis = 2;
	break;
    case PLANE_Y:
    case PLANE_ANYY:
	s_axis = 0;
	t_axis = 2;
	break;
    case PLANE_Z:
    case PLANE_ANYZ:
	s_axis = 0;
	t_axis = 1;
	break;
    }

    r_nearzi = 0;

    for (i = 0; i < lnumverts; i++) {
	// transform and project
	VectorSubtract(verts[vertpage][i].position, modelorg, local);
	TransformVector(local, transformed);

	if (transformed[2] < NEAR_CLIP)
	    transformed[2] = NEAR_CLIP;

	lzi = 1.0 / transformed[2];

	if (lzi > r_nearzi)	// for mipmap finding
	    r_nearzi = lzi;

	// FIXME: build x/yscale into transform?
	scale = xscale * lzi;
	u = (xcenter + scale * transformed[0]);
	if (u < r_refdef.fvrectx_adj)
	    u = r_refdef.fvrectx_adj;
	if (u > r_refdef.fvrectright_adj)
	    u = r_refdef.fvrectright_adj;

	scale = yscale * lzi;
	v = (ycenter - scale * transformed[1]);
	if (v < r_refdef.fvrecty_adj)
	    v = r_refdef.fvrecty_adj;
	if (v > r_refdef.fvrectbottom_adj)
	    v = r_refdef.fvrectbottom_adj;

	pverts[i].u = u;
	pverts[i].v = v;
	pverts[i].zi = lzi;
	pverts[i].s = verts[vertpage][i].position[s_axis];
	pverts[i].t = verts[vertpage][i].position[t_axis];
    }

// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z
// for each vertex
    r_polydesc.numverts = lnumverts;
    r_polydesc.nearzi = r_nearzi;
    r_polydesc.pcurrentface = fa;
    r_polydesc.pverts = pverts;

// draw the polygon
    D_DrawPoly();
}
Exemple #9
0
Vector3 Frame::AxisY(const Date& t, const Frame& ref) const
{
	return TransformVector(Vector3::j, t, ref);
}
Exemple #10
0
FVector2D SFxWidget::ComputeDesiredSize() const
{
	// Layout scale affects out desired size.
	return TransformVector(LayoutScale.Get(), ChildSlot.GetWidget()->GetDesiredSize());
}
//=================================================================================================================================
/// Measure overdraw from a particular viewpoint.
///
/// \param pCameraPosition  Camera position to use for this viewpoint.  The camera will be looking at the origin
/// \param nImageSize       Size of the pixel grid on each axis
/// \param bCullCCW         Set to true to cull CCW faces, otherwise cull CW faces.
/// \param fAvgODOut        A variable to receive the average overdraw per pixel.
///
/// \return                 False if out of memory.  True otherwise
//=================================================================================================================================
bool TootleRaytracer::ProcessViewpoint(const float* pCameraPosition,
                                       UINT         nImageSize,
                                       bool         bCullCCW,
                                       UINT&        nPixelHit,
                                       UINT&        nPixelDrawn)
{
    assert(pCameraPosition);

    if (nImageSize < 1)
    {
        nImageSize = 1;   // a strange 1x1 image
    }

    // build camera basis vectors
    Vec3f position(pCameraPosition);
    Vec3f viewDir = Normalize(position) * -1.0;
    Vec3f up;

    // Compute the up vector by performing 90 degree 2D rotation on the position vector
    //  (choose two good component vectors).
    if ((position[ 1 ] * position[ 1 ]) < (position[ 0 ] * position[ 0 ]))
    {
        up[ 0 ] = -position[ 2 ];
        up[ 1 ] =  0;
        up[ 2 ] =  position[ 0 ];
    }
    else
    {
        up[ 0 ] =  0;
        up[ 1 ] =  position[ 2 ];
        up[ 2 ] = -position[ 1 ];
    }

    up = Normalize(up);

    Matrix4f mLookAt = MatrixLookAt(position, Vec3f(0, 0, 0), up);

    // choose viewport size:
    // transform bounding box corners into viewing space
    // as we do this, track the bounding square of the x and y coordinates
    // we will take the size of the larger dimension to be the viewport size
    Vec3f corners[8];
    m_pCore->GetSceneBB().GetCorners(corners);

    float xmin =  FLT_MAX;
    float xmax = -FLT_MAX;
    float ymin =  FLT_MAX;
    float ymax = -FLT_MAX;

    for (int i = 0; i < 8; i++)
    {
        TransformVector(&corners[i], &mLookAt, &corners[i]);
        xmin = Min(xmin, corners[i].x);
        xmax = Max(xmax, corners[i].x);
        ymin = Min(ymin, corners[i].y);
        ymax = Max(ymax, corners[i].y);
    }

    float fViewSize = Max(xmax - xmin, ymax - ymin) * 2;
    //float fViewSize = sqrt(pow(xmax-xmin,2) + pow(ymax-ymin,2)); //Max( xmax - xmin, ymax - ymin );

    // build the camera
    JRTOrthoCamera camera(position, viewDir, up, fViewSize);

    // cull backfaces
    m_pCore->CullBackfaces(viewDir, bCullCCW);

    // iterate over the pixels that we're interested in
    float delta = 1.0f / nImageSize;
    float s = 0;
    float t = 0;
#ifdef DEBUG_IMAGES
    JRTPPMImage img(nImageSize, nImageSize);
#endif

    UINT nPixelDrawnTmp;

    nPixelHit   = 0;
    nPixelDrawn = 0;

    for (int i = 0; i < (int) nImageSize; i++)
    {
        for (int j = 0; j < (int) nImageSize; j++)
        {
            // compute the camera ray for this pixel
            Vec3f rayOrigin, rayDirection;
            camera.GetRay(s, t, &rayOrigin, &rayDirection);

            // trace through the scene data structures to find all hits
            TootleRayHit* pHitArray = 0;
            UINT nHits = 0;

            if (!m_pCore->FindAllHits(rayOrigin, rayDirection, &pHitArray, &nHits))
            {
                // ran out of memory
                return false;
            }

            if (nHits > 0)
            {
                nPixelHit++;

                // compute the number of triangles overdrawn for the pixel
                GetPixelDrawn(pHitArray, nHits, nPixelDrawnTmp);

                nPixelDrawn += nPixelDrawnTmp;
            }

#ifdef DEBUG_IMAGES
            float clr = nHits / 8.f;

            img.SetPixel(j, i, clr, clr, clr);

            /*if( nHits > 0 )
            {
               UINT nTriIndex = pHitArray[0].nFaceID;
               Vec3f normal = m_pMesh->GetFaceNormal( nTriIndex );
               normal /= 2;
               normal += Vec3f(0.5,0.5,0.5);
               img.SetPixel( j, i, normal.x, normal.y, normal.z );
            }*/

#endif

            s += delta;
        }

        t += delta;
        s = 0;
    }

#ifdef DEBUG_IMAGES
    static int nFrameNum = 0;
    char filename[100];
    sprintf(filename, "C:/tmp/images/view_%d.ppm", nFrameNum);
    img.SaveFile(filename);
    nFrameNum++;
#endif

    return true;
}
Exemple #12
0
// Draw the scene to the screen
void draw() {
	// Update time
	time += 2.0f * timeStep;

	/////////////////////// PART 1: SIMULATION /////////////////////////////////

	// Grab buffers for OpenCL
	acquireGLBuffer(particles.particleBuffer[particles.currentBuffer]);
	acquireGLBuffer(particles.particleBuffer[1 - particles.currentBuffer]);

	// Prepare to run some kernels
	cl_int numParticles = NUM_PARTICLES;
	cl_int gridElements = GRID_SIZE * GRID_SIZE * GRID_SIZE;

	cl_uint workSize[3] = {numParticles, 0, 0};
	cl_uint gridWorkSize[3] = {gridElements, 0, 0};
	cl_uint workgroupSize[3] = {256, 0, 0};

	// Clear grid
	clSetKernelArg(openCLKernels.gridClearKernel, 0, sizeof(cl_mem), &particles.gridSizeBuffer);
	clSetKernelArg(openCLKernels.gridClearKernel, 1, sizeof(cl_int), &gridElements);
	clRunKernel(openCLKernels.gridClearKernel, gridWorkSize, workgroupSize);

	// Compute grid positions
	clSetKernelArg(openCLKernels.gridKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.gridKernel, 1, sizeof(cl_mem), &particles.offsetBuffer);
	clSetKernelArg(openCLKernels.gridKernel, 2, sizeof(cl_mem), &particles.gridSizeBuffer);
	clSetKernelArg(openCLKernels.gridKernel, 3, sizeof(cl_int), &numParticles);
	clRunKernel(openCLKernels.gridKernel, workSize, workgroupSize);

	// Compute prefix sum for grid
	clSetKernelArg(openCLKernels.prefixSumKernel, 2, sizeof(cl_uint), (void*)&gridElements);

	int pingpong = 0;
	for(cl_int offset = 1; offset <= gridElements; offset *= 2) {
		if(offset == 1) {
			clSetKernelArg(openCLKernels.prefixSumKernel, 0, sizeof(cl_mem), (void*)&particles.gridSizeBuffer);
		}
		else {
			clSetKernelArg(openCLKernels.prefixSumKernel, 0, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[0] : particles.gridBuffer[1]));
		}
		clSetKernelArg(openCLKernels.prefixSumKernel, 1, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0]));
		clSetKernelArg(openCLKernels.prefixSumKernel, 3, sizeof(cl_int), (void*)&offset);
		clRunKernel(openCLKernels.prefixSumKernel, gridWorkSize, workgroupSize);
		pingpong = 1 - pingpong;
	}

	// Reorganize particles 
	clSetKernelArg(openCLKernels.gridReorderKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.gridReorderKernel, 1, sizeof(cl_mem), &particles.particleBuffer[1 - particles.currentBuffer]);
	clSetKernelArg(openCLKernels.gridReorderKernel, 2, sizeof(cl_mem), &particles.velocityBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.gridReorderKernel, 3, sizeof(cl_mem), &particles.velocityBuffer[1 - particles.currentBuffer]);
	clSetKernelArg(openCLKernels.gridReorderKernel, 4, sizeof(cl_mem), &particles.offsetBuffer);
	clSetKernelArg(openCLKernels.gridReorderKernel, 5, sizeof(cl_mem), (void*)&particles.gridSizeBuffer);
	clSetKernelArg(openCLKernels.gridReorderKernel, 6, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[0] : particles.gridBuffer[1]));
	clSetKernelArg(openCLKernels.gridReorderKernel, 7, sizeof(cl_int), &numParticles);
	clRunKernel(openCLKernels.gridReorderKernel, workSize, workgroupSize);

	particle* testData = (particle*)malloc(sizeof(cl_float) * numParticles * 4);

	// Swap particle buffers
	particles.currentBuffer = 1 - particles.currentBuffer;

	// Send new cell select buffer
	int cellSelect[27];
	for(int i = 0; i < 27; i++) {
		cellSelect[i] = i;
	}
	shuffle(cellSelect, 27);
	clEnqueueWriteBuffer(clCommandQueue(), particles.cellSelectBuffer, true, 0, 27 * sizeof(cl_int), cellSelect, 0, 0, 0);
	clFinish(clCommandQueue());

	// Recalculate densities and normalized pressure derivatives
	clSetKernelArg(openCLKernels.dataKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.dataKernel, 1, sizeof(cl_mem), &particles.dataBuffer);

	clSetKernelArg(openCLKernels.dataKernel, 2, sizeof(cl_mem), (void*)&particles.gridSizeBuffer);
	clSetKernelArg(openCLKernels.dataKernel, 3, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0]));

	clSetKernelArg(openCLKernels.dataKernel, 4, sizeof(cl_mem), (void*)&particles.cellSelectBuffer);

	clSetKernelArg(openCLKernels.dataKernel, 5, sizeof(cl_int), &numParticles);
	clRunKernel(openCLKernels.dataKernel, workSize, workgroupSize);

	// Send new cell select buffer
	cellSelect[27];
	for(int i = 0; i < 27; i++) {
		cellSelect[i] = i;
	}
	shuffle(cellSelect, 27);
	clEnqueueWriteBuffer(clCommandQueue(), particles.cellSelectBuffer, true, 0, 27 * sizeof(cl_int), cellSelect, 0, 0, 0);
	clFinish(clCommandQueue());

	// Integrate position
	float dT = timeStep;
	clSetKernelArg(openCLKernels.simulationKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.simulationKernel, 1, sizeof(cl_mem), &particles.particleBuffer[1 - particles.currentBuffer]);
	clSetKernelArg(openCLKernels.simulationKernel, 2, sizeof(cl_mem), &particles.velocityBuffer[particles.currentBuffer]);
	clSetKernelArg(openCLKernels.simulationKernel, 3, sizeof(cl_mem), &particles.velocityBuffer[1 - particles.currentBuffer]);
	clSetKernelArg(openCLKernels.simulationKernel, 4, sizeof(cl_mem), &particles.dataBuffer);
	
	clSetKernelArg(openCLKernels.simulationKernel, 5, sizeof(cl_mem), (void*)&particles.gridSizeBuffer);
	clSetKernelArg(openCLKernels.simulationKernel, 6, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0]));

	clSetKernelArg(openCLKernels.simulationKernel, 7, sizeof(cl_mem), (void*)&particles.cellSelectBuffer);

	clSetKernelArg(openCLKernels.simulationKernel, 8, sizeof(cl_float), &dT);
	clSetKernelArg(openCLKernels.simulationKernel, 9, sizeof(cl_float), &time);
	clSetKernelArg(openCLKernels.simulationKernel, 10, sizeof(cl_int), &numParticles);

	clSetKernelArg(openCLKernels.simulationKernel, 11, sizeof(cl_mem), &particles.terrainBuffer);

	PaddedVector windDir = PadVector(
		TransformVector(YAxisRotationMatrix(particles.windAngle), MakeVector(1.0f, 0.0f, 0.0f))
	);
	clSetKernelArg(openCLKernels.simulationKernel, 12, sizeof(cl_float) * 4, &windDir);
	clSetKernelArg(openCLKernels.simulationKernel, 13, sizeof(cl_float), &particles.windPower);

	clRunKernel(openCLKernels.simulationKernel, workSize, workgroupSize);

	// Release buffers back to OpenGL
	releaseGLBuffer(particles.particleBuffer[particles.currentBuffer]);
	releaseGLBuffer(particles.particleBuffer[1 - particles.currentBuffer]);

	// Swap particle buffers
	particles.currentBuffer = 1 - particles.currentBuffer;

	//////////////////////// PART 2: RENDERIING ////////////////////////////////

	// Clear everything first thing.
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.backgroundFBO);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	// Activate shader.
	glUseProgram(objectShader.shaderProgram);

	// Set projection
	Matrix projection = PerspectiveMatrix(
		45.0f,
		(float)WINDOW_WIDTH/(float)WINDOW_HEIGHT,
		0.01f,
		100.0f
	);
	MatrixAsUniform(objectShader.projectionMatrix, projection);
	
	// Vertices
	glBindBuffer(GL_ARRAY_BUFFER, terrain.vertexBuffer);
	glVertexAttribPointer(
		objectShader.vertexPosition,
		4,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 4,
		(void*)0
	);
	glEnableVertexAttribArray(objectShader.vertexPosition);
	
	// Set modelview according to camera
	Matrix rot = lookatMatrix(camera.pos, VectorAdd(camera.pos, camera.front), camera.up);
	rot = MatrixMul(RotationMatrix(camera.elevation, MakeVector(1, 0, 0)), rot);
	Matrix trans = TranslationMatrix(-camera.pos.x, -camera.pos.y, -camera.pos.z);
	Matrix modelview =  MatrixMul(rot, trans);
	MatrixAsUniform(objectShader.modelviewMatrix, modelview);

	// Normal view matrix - inverse transpose of modelview.
	Matrix normalview = MatrixTranspose(FastMatrixInverse(modelview));
	MatrixAsUniform(objectShader.normalviewMatrix, normalview);

	// Set heightmap texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, terrain.heightTexture );
	glUniform1i(objectShader.terrainTexture, 0);

	// Set color textures
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, terrain.lowTexture);
	glUniform1i(objectShader.lowTexture, 1);

	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, terrain.highTexture);
	glUniform1i(objectShader.highTexture, 2);

	// Turn off culling
	glDisable(GL_CULL_FACE);

	// Send element buffer to GPU and draw.
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrain.elementBuffer);

	glDrawElements(
		GL_TRIANGLES,
		512 * 512 * 6,
		GL_UNSIGNED_INT,
		(void*)0
	);
	
	// Turn culling back on
	glEnable(GL_CULL_FACE);

	// Switch to low-res viewport
	glViewport(0, 0, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER);

	// Low-res projection matrix
	Matrix projectionLowres = PerspectiveMatrix(
		45.0f,
		(float)(WINDOW_WIDTH / RESOLUTION_DIVIDER) / (float)(WINDOW_HEIGHT / RESOLUTION_DIVIDER),
		0.01f,
		100.0f
	);

	// Activate particle depth FBO
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleFBO[0]);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Activate shader
	glUseProgram(particleShader.shaderProgram);

	// Set textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture);
	glUniform1i(particleShader.terrainTexture, 0);

	// Send uniforms
	MatrixAsUniform(particleShader.modelviewMatrix, modelview);
	MatrixAsUniform(particleShader.projectionMatrix, projectionLowres);
	glUniform2f(particleShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER);

	// Bind new buffer and set up arrtibutes
	glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]);
	glVertexAttribPointer(
		particleShader.vertexPosition,
		4,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 4,
		(void*)0
	);
	glEnableVertexAttribArray(particleShader.vertexPosition);

	// Bind element buffer and draw particles
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer);
	glDrawElements(
		GL_POINTS,
		NUM_PARTICLES,
		GL_UNSIGNED_INT,
		(void*)0
	);

	// Activate particle thickness FBO
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleThicknessFBO[0]);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Activate shader
	glUseProgram(particleThicknessShader.shaderProgram);

	// Send uniforms
	MatrixAsUniform(particleThicknessShader.modelviewMatrix, modelview);
	MatrixAsUniform(particleThicknessShader.projectionMatrix, projectionLowres);
	glUniform2f(particleThicknessShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER);

	// Set textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture);
	glUniform1i(particleThicknessShader.terrainTexture, 0);

	// Bind new buffer and set up arrtibutes
	glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]);
	glVertexAttribPointer(
		particleThicknessShader.vertexPosition,
		4,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 4,
		(void*)0
	);
	glEnableVertexAttribArray(particleThicknessShader.vertexPosition);

	// Enable additive blending and disable depth test
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);
	glDisable(GL_DEPTH_TEST);

	// Bind element buffer and draw particles, this time rendering thickness map
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer);
	glDrawElements(
		GL_POINTS,
		NUM_PARTICLES,
		GL_UNSIGNED_INT,
		(void*)0
	);
	
	// Turn blending back off and depth test back on
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);

	// Activate particle velocity FBO
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.velocityFBO);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Activate shader
	glUseProgram(particleVelocityShader.shaderProgram);

	// Send uniforms
	MatrixAsUniform(particleVelocityShader.modelviewMatrix, modelview);
	MatrixAsUniform(particleVelocityShader.projectionMatrix, projectionLowres);
	glUniform2f(particleVelocityShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER);

	// Bind new buffer and set up arrtibutes
	glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]);
	glVertexAttribPointer(
		particleVelocityShader.vertexPosition,
		4,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 4,
		(void*)0
	);
	glEnableVertexAttribArray(particleVelocityShader.vertexPosition);

	// Bind element buffer and draw particles, this time rendering velocity map
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer);
	glDrawElements(
		GL_POINTS,
		NUM_PARTICLES,
		GL_UNSIGNED_INT,
		(void*)0
	);

	// Curvature flow smoothing begins
	glUseProgram(curvatureFlowShader.shaderProgram);

	// Send uniforms
	glUniform1i(curvatureFlowShader.particleTexture, 0);

	glUniform2f(curvatureFlowShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER);
	MatrixAsUniform(curvatureFlowShader.projectionMatrix, projectionLowres);

	// Prepare state
	glActiveTexture(GL_TEXTURE0);
	glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer);
	glVertexAttribPointer(
		curvatureFlowShader.vertexPosition,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 3,
		(void*)0
	);
	glEnableVertexAttribArray(curvatureFlowShader.vertexPosition);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer);

	// Smoothing loop
	glDisable(GL_DEPTH_TEST);
	pingpong = 0;
	for(int i = 0; i < smoothingIterations; i++) {
		// Bind no FBO
		glBindFramebuffer(GL_FRAMEBUFFER, 0);

		// Bind texture
		glBindTexture(GL_TEXTURE_2D, framebuffers.particleTexture[pingpong]);

		// Activate proper FBO and clear
		glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleFBO[1 - pingpong]);

		// Draw a quad
		glDrawElements(
			GL_TRIANGLES,
			6,
			GL_UNSIGNED_INT,
			(void*)0
		);

		// Switch buffers
		pingpong = 1 - pingpong;
	}
	glEnable(GL_DEPTH_TEST);

	// Activate particle color FBO
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleColorFBO);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Liquid shading shader
	glUseProgram(liquidShadeShader.shaderProgram);

	// Bind and set textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, framebuffers.particleTexture[0]);
	glUniform1i(liquidShadeShader.particleTexture, 0);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, framebuffers.particleThicknessTexture[0]);
	glUniform1i(liquidShadeShader.particleThicknessTexture, 1);

	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, terrain.envTexture);
	glUniform1i(liquidShadeShader.environmentTexture, 2);

	glActiveTexture(GL_TEXTURE3);
	glBindTexture(GL_TEXTURE_2D, framebuffers.particleVelocityTexture);
	glUniform1i(liquidShadeShader.velocityTexture, 3);

	// Send uniforms
	glUniform2f(liquidShadeShader.screenSize, WINDOW_WIDTH, WINDOW_HEIGHT);
	MatrixAsUniform(liquidShadeShader.modelviewMatrix, modelview);
	MatrixAsUniform(liquidShadeShader.projectionMatrix, projection);
	glUniform1i(liquidShadeShader.useThickness, useThickness);

	// Draw a quad
    glDisable(GL_DEPTH_TEST);
	glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer);
	glVertexAttribPointer(
		liquidShadeShader.vertexPosition,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 3,
		(void*)0
	);
	glEnableVertexAttribArray(liquidShadeShader.vertexPosition);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer);
	glDrawElements(
		GL_TRIANGLES,
		6,
		GL_UNSIGNED_INT,
		(void*)0
	);
	glEnable(GL_DEPTH_TEST);

	// Switch back to full-res viewport
	glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

	// Deactivate FBOs
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Compose shader
	glUseProgram(compositionShader.shaderProgram);

	// Bind and set textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, terrain.envTexture);
	glUniform1i(compositionShader.backgroundTexture, 0);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, framebuffers.particleColorTexture);
	glUniform1i(compositionShader.particleTexture, 1);

	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture);
	glUniform1i(compositionShader.terrainTexture, 2);

	// Send uniforms
	MatrixAsUniform(compositionShader.modelviewMatrix, modelview);
	
	// Draw a quad
    glDisable(GL_DEPTH_TEST);
	glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer);
	glVertexAttribPointer(
		compositionShader.vertexPosition,
		3,
		GL_FLOAT,
		GL_FALSE,
		sizeof(GLfloat) * 3,
		(void*)0
	);
	glEnableVertexAttribArray(compositionShader.vertexPosition);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer);
	glDrawElements(
		GL_TRIANGLES,
		6,
		GL_UNSIGNED_INT,
		(void*)0
	);
	glEnable(GL_DEPTH_TEST);

	// Switch drawing area and displayed area.
	glutSwapBuffers();
}
/********************************************************
 *
 *
 * Draw Robot
 *
 *
 ********************************************************/
void Virtual3dCharacterViewer::glDrawBody(Character3DBody& body)
{
    glPushMatrix();


    // getHipPos() ; // get Hip's Position from the IK calculator .
    LocateHip (body);
    body.HipPosInCamera = getCurTranslation () ;
    body.HipPosInScreen = getScreenPos(body.HipPosInCamera) ;
    RotateHip(body) ;
    glPushMatrix();     // save the Hip Matrix
    drawHip (body) ;

    glTranslatef( 0.0, body.Model.LenHipToChest, 0.0 ) ;
    RotateChest (body);
    drawChest (body) ;


    glTranslatef(0.0, body.Model.LenChestToNeck, 0.0);

    body.NeckPosInCamera = getCurTranslation () ;
    body.NeckPos = TransformVector( WorldMatInv, body.NeckPosInCamera ) ;
    body.NeckPosInScreen = getScreenPos(body.NeckPosInCamera) ;


    glPushMatrix();     // save the Neck Matrix

    RotateLeftShoulder(body);
    drawLeftShoulder(body);

    glTranslatef(body.Model.LenNeckToShoulder, 0.0, 0.0);
    RotateLeftUpperArm(body);
    drawLeftUpperArm(body);


    glTranslatef(body.Model.LenShoulderToElbow, 0.0, 0.0);
    RotateLeftLowerArm(body);
    drawLeftLowerArm(body);



    glTranslatef(body.Model.LenElbowToWrist, 0.0, 0.0);

    body.LeftWristPosInCamera = getCurTranslation () ;
    Vector3D bias(-1,0,0) ;
    body.LeftWristPos = TransformVector( WorldMatInv, body.LeftWristPosInCamera );
    body.LeftWristPosInScreen = getScreenPos(body.LeftWristPosInCamera) ;

    RotateLeftHand(body);
    drawLeftHand(body);


    glPopMatrix();      // reload the Neck Matrix
    glPushMatrix();     // restore the Neck Matrix again .


    RotateRightShoulder(body);
    drawRightShoulder(body);

    glTranslatef(-body.Model.LenNeckToShoulder, 0.0, 0.0);
    RotateRightUpperArm(body);
    drawRightUpperArm(body);


    glTranslatef(-body.Model.LenShoulderToElbow, 0.0, 0.0);
    RotateRightLowerArm(body);
    drawRightLowerArm(body);

    glTranslatef(-body.Model.LenElbowToWrist, 0.0, 0.0);

    body.RightWristPosInCamera = getCurTranslation () ;
    body.RightWristPos = TransformVector( WorldMatInv, body.RightWristPosInCamera ) ;
    body.RightWristPosInScreen = getScreenPos(body.RightWristPosInCamera) ;

    RotateRightHand(body);
    drawRightHand(body);


    glPopMatrix();      // reload the Neck Matrix again .

    RotateHead(body);
    drawHead (body);
    glTranslatef(0.0, body.Model.LenNeckToHead, 0.0);
    body.HeadPosInCamera = getCurTranslation () ;
    body.HeadPos = TransformVector( WorldMatInv, body.HeadPosInCamera ) ;
    body.HeadPosInScreen = getScreenPos(body.HeadPosInCamera) ;

    glPopMatrix();      // reload the Hip Matrix .
    glPushMatrix();     // restore the Hip Matrix again.

    RotateLeftThighRoot (body);
    drawLeftThighRoot(body);

    glTranslatef(body.Model.LenHipToThigh, 0.0, 0.0);

    RotateLeftThigh (body) ;
    drawLeftThigh(body);

    glTranslatef(0.0, -body.Model.LenThighToKnee, 0.0);

    RotateLeftShank(body);
    drawLeftShank(body);

    glTranslatef(0.0, -body.Model.LenKneeToAnkle, 0.0);
    body.LeftAnklePosInCamera = getCurTranslation();
    body.LeftAnklePos = TransformVector( WorldMatInv, body.LeftAnklePosInCamera ) ;
    body.LeftAnklePosInScreen = getScreenPos(body.LeftAnklePosInCamera) ;

    RotateLeftFoot (body);
    drawLeftFoot(body);


    glPopMatrix();      // reload the Hip Matrix again.


    RotateRightThighRoot (body);
    drawRightThighRoot(body);

    glTranslatef(-body.Model.LenHipToThigh, 0.0, 0.0);

    RotateRightThigh (body) ;
    drawRightThigh(body);

    glTranslatef(0.0, -body.Model.LenThighToKnee, 0.0);

    RotateRightShank(body);
    drawRightShank(body);

    glTranslatef(0.0, -body.Model.LenKneeToAnkle, 0.0);
    body.RightAnklePosInCamera = getCurTranslation();
    body.RightAnklePos = TransformVector( WorldMatInv, body.RightAnklePosInCamera ) ;
    body.RightAnklePosInScreen = getScreenPos(body.RightAnklePosInCamera) ;



    RotateRightFoot (body);
    drawRightFoot(body);


    glPopMatrix();
}
Exemple #14
0
void TransformPlane(Plane& out, const Plane& in, const Float4x4& transform)
{
    TransformVector( out.normal, in.normal, transform );
    out.distance = in.distance + DotProduct( out.normal, transform.WAxis );
}
Exemple #15
0
// Frame case
bool Model3D::FindPositions_Frame(bool UseModelTransform,
                                  GLshort FrameIndex, GLfloat MixFrac,
                                  GLshort AddlFrameIndex)
{
  // Bad inputs: do nothing and return false

  if (Frames.empty()) {
    return false;
  }

  size_t NumBones = Bones.size();
  if (FrameIndex < 0 || NumBones*FrameIndex >= Frames.size()) {
    return false;
  }

  if (InverseVSIndices.empty()) {
    BuildInverseVSIndices();
  }

  size_t NumVertices = VtxSrcIndices.size();
  Positions.resize(3*NumVertices);

  // Set sizes:
  BoneMatrices.resize(NumBones);
  BoneStack.resize(NumBones);

  // Find which frame; remember that frame data comes in [NumBones] sets
  Model3D_Frame *FramePtr = &Frames[NumBones*FrameIndex];
  Model3D_Frame *AddlFramePtr = &Frames[NumBones*AddlFrameIndex];

  // Find the individual-bone transformation matrices:
  for (size_t ib=0; ib<NumBones; ib++)
    FindBoneTransform(BoneMatrices[ib],Bones[ib],
                      FramePtr[ib],MixFrac,AddlFramePtr[ib]);

  // Find the cumulative-bone transformation matrices:
  int StackIndx = -1;
  size_t Parent = UNONE;
  for (unsigned int ib=0; ib<NumBones; ib++)
  {
    Model3D_Bone& Bone = Bones[ib];

    // Do the pop-push with the stack
    // to get the bone's parent bone
    if (TEST_FLAG(Bone.Flags,Model3D_Bone::Pop)) {
      if (StackIndx >= 0) {
        Parent = BoneStack[StackIndx--];
      }
      else{
        Parent = UNONE;
      }
    }
    if (TEST_FLAG(Bone.Flags,Model3D_Bone::Push)) {
      StackIndx = MAX(StackIndx,-1);
      BoneStack[++StackIndx] = Parent;
    }

    // Do the transform!
    if (Parent != UNONE) {
      Model3D_Transform Res;
      TMatMultiply(Res,BoneMatrices[Parent],BoneMatrices[ib]);
      obj_copy(BoneMatrices[ib],Res);
    }

    // Default: parent of next bone is current bone
    Parent = ib;
  }

  bool NormalsPresent = !NormSources.empty();
  if (NormalsPresent) {
    Normals.resize(NormSources.size());
  }

  for (unsigned ivs=0; ivs<VtxSources.size(); ivs++)
  {
    Model3D_VertexSource& VS = VtxSources[ivs];
    GLfloat Position[3];

    if (VS.Bone0 >= 0) {
      Model3D_Transform& T0 = BoneMatrices[VS.Bone0];
      TransformPoint(Position,VS.Position,T0);

      if (NormalsPresent) {
        for (int iv=InvVSIPointers[ivs]; iv<InvVSIPointers[ivs+1]; iv++)
        {
          int Indx = 3*InverseVSIndices[iv];
          TransformVector(NormBase() + Indx, NormSrcBase() + Indx, T0);
        }
      }

      GLfloat Blend = VS.Blend;
      if (VS.Bone1 >= 0 && Blend != 0) {
        Model3D_Transform& T1 = BoneMatrices[VS.Bone1];
        GLfloat PosExtra[3];
        GLfloat PosDiff[3];
        TransformPoint(PosExtra,VS.Position,T1);
        VecSub(PosExtra,Position,PosDiff);
        VecScalarMultTo(PosDiff,Blend);
        VecAddTo(Position,PosDiff);

        if (NormalsPresent) {
          for (int iv=InvVSIPointers[ivs]; iv<InvVSIPointers[ivs+1]; iv++)
          {
            int Indx = 3*InverseVSIndices[iv];
            GLfloat NormExtra[3];
            GLfloat NormDiff[3];
            GLfloat *OrigNorm = NormSrcBase() + Indx;
            GLfloat *Norm = NormBase() + Indx;
            TransformVector(NormExtra,OrigNorm,T1);
            VecSub(NormExtra,Norm,NormDiff);
            VecScalarMultTo(NormDiff,Blend);
            VecAddTo(Norm,NormDiff);
          }
        }
      }
    }
    else                // The assumed root bone (identity transformation)
    {
      VecCopy(VS.Position,Position);
      if (NormalsPresent) {
        for (int iv=InvVSIPointers[ivs]; iv<InvVSIPointers[ivs+1]; iv++)
        {
          int Indx = 3*InverseVSIndices[iv];
          VecCopy(NormSrcBase() + Indx, NormBase() + Indx);
        }
      }
    }

    // Copy found position into vertex array!
    for (int iv=InvVSIPointers[ivs]; iv<InvVSIPointers[ivs+1]; iv++)
      VecCopy(Position,PosBase() + 3*InverseVSIndices[iv]);
  }

  if (UseModelTransform) {
    GLfloat *PP = PosBase();
    for (size_t k=0; k<Positions.size()/3; k++, PP+=3)
    {
      GLfloat Position[3];
      TransformPoint(Position,PP,TransformPos);
      VecCopy(Position,PP);
    }
    GLfloat *NP = NormBase();
    for (size_t k=0; k<Normals.size()/3; k++, NP+=3)
    {
      GLfloat Normal[3];
      TransformVector(Normal,NP,TransformNorm);
      VecCopy(Normal,NP);
    }
  }

  return true;
}
Exemple #16
0
FVector2D FGeometry::GetDrawSize() const
{
	return TransformVector(GetAccumulatedLayoutTransform(), Size);
}
Exemple #17
0
bool Model3D::FindPositions_Sequence(bool UseModelTransform, GLshort SeqIndex,
                                     GLshort FrameIndex, GLfloat MixFrac,
                                     GLshort AddlFrameIndex)
{
  // Bad inputs: do nothing and return false

  GLshort NumSF = NumSeqFrames(SeqIndex);
  if (NumSF <= 0) {
    return false;
  }

  if (FrameIndex < 0 || FrameIndex >= NumSF) {
    return false;
  }

  Model3D_Transform TSF;

  Model3D_SeqFrame& SF = SeqFrames[SeqFrmPointers[SeqIndex] + FrameIndex];

  if (MixFrac != 0 && AddlFrameIndex != FrameIndex) {
    if (AddlFrameIndex < 0 || AddlFrameIndex >= NumSF) {
      return false;
    }

    Model3D_SeqFrame& ASF =
      SeqFrames[SeqFrmPointers[SeqIndex] + AddlFrameIndex];
    FindFrameTransform(TSF,SF,MixFrac,ASF);

    if (!FindPositions_Frame(false,SF.Frame,MixFrac,ASF.Frame)) {
      return false;
    }
  }
  else
  {
    if (!FindPositions_Frame(false,SF.Frame)) {
      return false;
    }
    FindFrameTransform(TSF,SF,0,SF);
  }

  Model3D_Transform TTot;
  if (UseModelTransform) {
    TMatMultiply(TTot,TransformPos,TSF);
  }
  else{
    obj_copy(TTot,TSF);
  }

  size_t NumVerts = Positions.size()/3;
  GLfloat *Pos = PosBase();
  for (size_t iv=0; iv<NumVerts; iv++)
  {
    GLfloat NewPos[3];
    TransformPoint(NewPos,Pos,TTot);
    VecCopy(NewPos,Pos);
    Pos += 3;
  }

  bool NormalsPresent = !NormSources.empty();
  if (NormalsPresent) {
    // OK, since the bones don't change bulk
    if (UseModelTransform) {
      TMatMultiply(TTot,TransformNorm,TSF);
    }
    else{
      obj_copy(TTot,TSF);
    }

    GLfloat *Norm = NormBase();
    for (size_t iv=0; iv<NumVerts; iv++)
    {
      GLfloat NewNorm[3];
      TransformVector(NewNorm,Norm,TTot);
      VecCopy(NewNorm,Norm);
      Norm += 3;
    }
  }

  return true;
}
Exemple #18
0
bool SCSM::BuildSRLocation(logoInfor &logoFeat) {
    // build point vector
    for (int i = 0; i < logoFeat.pointIndexofClusters.size(); ++i) {
        if (!logoFeat.pointIndexofClusters[i].empty()) {
            ObjKeywordNum onecenterinfor;
            onecenterinfor.logoName = logoFeat.baseinfor.logoName;
            onecenterinfor.num = logoFeat.pointIndexofClusters[i].size();
            onecenterinfor.pointvec.reserve(onecenterinfor.num);
            onecenterinfor.allRSvec.reserve(mapnum);
            onecenterinfor.df = 1.0*onecenterinfor.num/logoFeat.keypointNum;
            for (int j = 0 ; j < onecenterinfor.num; j++) {
                KeyPoint keyloc = logoFeat.keypoints[logoFeat.pointIndexofClusters[i][j]];
//                 keyloc.pt.x = QuantizeLocation(keyloc.pt.x, logoFeat.baseinfor.width);  // 量化坐标
//                 keyloc.pt.y = QuantizeLocation(keyloc.pt.y, logoFeat.baseinfor.height);  // 量化坐标
                onecenterinfor.pointvec.push_back(keyloc.pt);
            }
            onecenterinfor.clustercenter = i;
            objIfor.push_back(onecenterinfor);
        }
    }
    // compute different center to point vectors in different scales and rotations
    CvPoint orig_point, trans_point;
    CvPoint2D32f orig_vector, trans_vector;
    for (int i = 0; i < objIfor.size(); ++i) {
        // original scale and rotation
        ObjkeywdVec objkeywdlocation_orig;
        objkeywdlocation_orig.SR.rotation = 0;
        objkeywdlocation_orig.SR.scale = 1;
        objkeywdlocation_orig.pLocation.reserve(objIfor[i].num);
        objkeywdlocation_orig.PTCvec.reserve(objIfor[i].num);
        for (int j = 0; j < objIfor[i].num; j++) {
            orig_point = objIfor[i].pointvec[j];
            TransformPoint(objkeywdlocation_orig.SR.rotation, objkeywdlocation_orig.SR.scale,
                orig_point, trans_point, trans_vector);
            objkeywdlocation_orig.pLocation.push_back(trans_point);
            objkeywdlocation_orig.PTCvec.push_back(trans_vector);
        }
        // other scales and rotations
        for (int j = 0; j < nQuantizedNS; ++j) {
            for (int  k= 0; k < nQuantizedNR; ++k) {
                if (j == 2 && k == 0) {
                    objIfor[i].allRSvec.push_back(objkeywdlocation_orig);
                    continue;
                }
                ObjkeywdVec objkeywdlocation_other;
                objkeywdlocation_other.SR.rotation = k;
                objkeywdlocation_other.SR.scale = 0.5 + j/4.0;
                objkeywdlocation_other.pLocation.reserve(objIfor[i].num);
                objkeywdlocation_other.PTCvec.reserve(objIfor[i].num);
                for (int l = 0; l < objIfor[i].pointvec.size(); l++) {
                    orig_vector = objkeywdlocation_orig.PTCvec[l];
                    TransformVector(objkeywdlocation_other.SR.rotation, objkeywdlocation_other.SR.scale,
                        orig_vector, trans_point, trans_vector);
                    objkeywdlocation_other.pLocation.push_back(trans_point);
                    objkeywdlocation_other.PTCvec.push_back(trans_vector);
                }
                objIfor[i].allRSvec.push_back(objkeywdlocation_other);
            }
        }
    }
    return true;
}