Exemple #1
0
static size_t BuildIslandsAndEstimateStepperMemoryRequirements(
    dxWorldProcessIslandsInfo &islandsinfo, dxWorldProcessMemArena *memarena, 
    dxWorld *world, dReal stepsize, dmemestimate_fn_t stepperestimate)
{
    size_t maxreq = 0;

    // handle auto-disabling of bodies
    dInternalHandleAutoDisabling (world,stepsize);

    unsigned int nb = world->nb, nj = world->nj;
    // Make array for island body/joint counts
    unsigned int *islandsizes = memarena->AllocateArray<unsigned int>(2 * (size_t)nb);
    unsigned int *sizescurr;

    // make arrays for body and joint lists (for a single island) to go into
    dxBody **body = memarena->AllocateArray<dxBody *>(nb);
    dxJoint **joint = memarena->AllocateArray<dxJoint *>(nj);

    BEGIN_STATE_SAVE(memarena, stackstate) {
        // allocate a stack of unvisited bodies in the island. the maximum size of
        // the stack can be the lesser of the number of bodies or joints, because
        // new bodies are only ever added to the stack by going through untagged
        // joints. all the bodies in the stack must be tagged!
        unsigned int stackalloc = (nj < nb) ? nj : nb;
        dxBody **stack = memarena->AllocateArray<dxBody *>(stackalloc);

        {
            // set all body/joint tags to 0
            for (dxBody *b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0;
            for (dxJoint *j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0;
        }

        sizescurr = islandsizes;
        dxBody **bodystart = body;
        dxJoint **jointstart = joint;
        for (dxBody *bb=world->firstbody; bb; bb=(dxBody*)bb->next) {
            // get bb = the next enabled, untagged body, and tag it
            if (!bb->tag) {
                if (!(bb->flags & dxBodyDisabled)) {
                    bb->tag = 1;

                    dxBody **bodycurr = bodystart;
                    dxJoint **jointcurr = jointstart;

                    // tag all bodies and joints starting from bb.
                    *bodycurr++ = bb;

                    unsigned int stacksize = 0;
                    dxBody *b = bb;

                    while (true) {
                        // traverse and tag all body's joints, add untagged connected bodies
                        // to stack
                        for (dxJointNode *n=b->firstjoint; n; n=n->next) {
                            dxJoint *njoint = n->joint;
                            if (!njoint->tag) {
                                if (njoint->isEnabled()) {
                                    njoint->tag = 1;
                                    *jointcurr++ = njoint;

                                    dxBody *nbody = n->body;
                                    // Body disabled flag is not checked here. This is how auto-enable works.
                                    if (nbody && nbody->tag <= 0) {
                                        nbody->tag = 1;
                                        // Make sure all bodies are in the enabled state.
                                        nbody->flags &= ~dxBodyDisabled;
                                        stack[stacksize++] = nbody;
                                    }
                                } else {
                                    njoint->tag = -1; // Used in Step to prevent search over disabled joints (not needed for QuickStep so far)
                                }
                            }
                        }
                        dIASSERT(stacksize <= (unsigned int)world->nb);
                        dIASSERT(stacksize <= (unsigned int)world->nj);

                        if (stacksize == 0) {
                            break;
                        }

                        b = stack[--stacksize];	// pop body off stack
                        *bodycurr++ = b;	// put body on body list
                    }

                    unsigned int bcount = (unsigned int)(bodycurr - bodystart);
                    unsigned int jcount = (unsigned int)(jointcurr - jointstart);
                    dIASSERT((size_t)(bodycurr - bodystart) <= (size_t)UINT_MAX);
                    dIASSERT((size_t)(jointcurr - jointstart) <= (size_t)UINT_MAX);

                    sizescurr[dxISE_BODIES_COUNT] = bcount;
                    sizescurr[dxISE_JOINTS_COUNT] = jcount;
                    sizescurr += dxISE__MAX;

                    size_t islandreq = stepperestimate(bodystart, bcount, jointstart, jcount);
                    maxreq = (maxreq > islandreq) ? maxreq : islandreq;

                    bodystart = bodycurr;
                    jointstart = jointcurr;
                } else {
                    bb->tag = -1; // Not used so far (assigned to retain consistency with joints)
                }
            }
        }
    } END_STATE_SAVE(memarena, stackstate);
Exemple #2
0
void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper)
{
  dxBody *b,*bb,**body;
  dxJoint *j,**joint;

  // nothing to do if no bodies
  if (world->nb <= 0) return;

  // handle auto-disabling of bodies
  dInternalHandleAutoDisabling (world,stepsize);

  // make arrays for body and joint lists (for a single island) to go into
  body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*));
  joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*));
  int bcount = 0;	// number of bodies in `body'
  int jcount = 0;	// number of joints in `joint'

  // set all body/joint tags to 0
  for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0;
  for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0;

  // allocate a stack of unvisited bodies in the island. the maximum size of
  // the stack can be the lesser of the number of bodies or joints, because
  // new bodies are only ever added to the stack by going through untagged
  // joints. all the bodies in the stack must be tagged!
  int stackalloc = (world->nj < world->nb) ? world->nj : world->nb;
  dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*));

  for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) {
    // get bb = the next enabled, untagged body, and tag it
    if (bb->tag || (bb->flags & dxBodyDisabled)) continue;
    bb->tag = 1;

    // tag all bodies and joints starting from bb.
    int stacksize = 0;
    b = bb;
    body[0] = bb;
    bcount = 1;
    jcount = 0;
    goto quickstart;
    while (stacksize > 0) {
      b = stack[--stacksize];	// pop body off stack
      body[bcount++] = b;	// put body on body list
      quickstart:

      // traverse and tag all body's joints, add untagged connected bodies
      // to stack
      for (dxJointNode *n=b->firstjoint; n; n=n->next) {
	if (!n->joint->tag) {
	  n->joint->tag = 1;
	  joint[jcount++] = n->joint;
	  if (n->body && !n->body->tag) {
	    n->body->tag = 1;
	    stack[stacksize++] = n->body;
	  }
	}
      }
      dIASSERT(stacksize <= world->nb);
      dIASSERT(stacksize <= world->nj);
    }

    // now do something with body and joint lists
    stepper (world,body,bcount,joint,jcount,stepsize);

    // what we've just done may have altered the body/joint tag values.
    // we must make sure that these tags are nonzero.
    // also make sure all bodies are in the enabled state.
    int i;
    for (i=0; i<bcount; i++) {
      body[i]->tag = 1;
      body[i]->flags &= ~dxBodyDisabled;
    }
    for (i=0; i<jcount; i++) joint[i]->tag = 1;
  }

  // if debugging, check that all objects (except for disabled bodies,
  // unconnected joints, and joints that are connected to disabled bodies)
  // were tagged.
# ifndef dNODEBUG
  for (b=world->firstbody; b; b=(dxBody*)b->next) {
    if (b->flags & dxBodyDisabled) {
      if (b->tag) dDebug (0,"disabled body tagged");
    }
    else {
      if (!b->tag) dDebug (0,"enabled body not tagged");
    }
  }
  for (j=world->firstjoint; j; j=(dxJoint*)j->next) {
    if ((j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0) ||
	(j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0)) {
      if (!j->tag) dDebug (0,"attached enabled joint not tagged");
    }
    else {
      if (j->tag) dDebug (0,"unattached or disabled joint tagged");
    }
  }
# endif
}
static void
processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations)
{
	dxBody *b, *bb, **body;
	dxJoint *j, **joint;

	// nothing to do if no bodies
	if (world->nb <= 0)
		return;

	dInternalHandleAutoDisabling (world,stepsize);

	// make arrays for body and joint lists (for a single island) to go into
	body = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *));
	joint = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *));
	int bcount = 0;				// number of bodies in `body'
	int jcount = 0;				// number of joints in `joint'
	int tbcount = 0;
	int tjcount = 0;
	
	// set all body/joint tags to 0
	for (b = world->firstbody; b; b = (dxBody *) b->next)
		b->tag = 0;
	for (j = world->firstjoint; j; j = (dxJoint *) j->next)
		j->tag = 0;

	// allocate a stack of unvisited bodies in the island. the maximum size of
	// the stack can be the lesser of the number of bodies or joints, because
	// new bodies are only ever added to the stack by going through untagged
	// joints. all the bodies in the stack must be tagged!
	int stackalloc = (world->nj < world->nb) ? world->nj : world->nb;
	dxBody **stack = (dxBody **) ALLOCA (stackalloc * sizeof (dxBody *));
	int *autostack = (int *) ALLOCA (stackalloc * sizeof (int));

	for (bb = world->firstbody; bb; bb = (dxBody *) bb->next)
	{
		// get bb = the next enabled, untagged body, and tag it
		if (bb->tag || (bb->flags & dxBodyDisabled))
			continue;
		bb->tag = 1;

		// tag all bodies and joints starting from bb.
		
		int stacksize = 0;
		int firsttime = 1;
		
		int autoDepth = GetGlobalData()->autoEnableDepth;
		b = bb;
		body[0] = bb;
		bcount = 1;
		jcount = 0;
		
		while (stacksize > 0 || firsttime)
		{
		    if (!firsttime)
		    {
			    b = stack[--stacksize];	// pop body off stack
			    autoDepth = autostack[stacksize];
			    body[bcount++] = b;	// put body on body list
		    }
		    else
		    {
		        firsttime = 0;
		    }
		 
			// traverse and tag all body's joints, add untagged connected bodies
			// to stack
			for (dxJointNode * n = b->firstjoint; n; n = n->next)
			{
				if (!n->joint->tag)
				{
					int thisDepth = GetGlobalData()->autoEnableDepth;
					n->joint->tag = 1;
					joint[jcount++] = n->joint;
					if (n->body && !n->body->tag)
					{
						if (n->body->flags & dxBodyDisabled)
							thisDepth = autoDepth - 1;
						if (thisDepth < 0)
							continue;
						n->body->flags &= ~dxBodyDisabled;
						n->body->tag = 1;
						autostack[stacksize] = thisDepth;
						stack[stacksize++] = n->body;
					}
				}
			}
		}

		// now do something with body and joint lists
		dInternalStepIslandFast (world, body, bcount, joint, jcount, stepsize, maxiterations);

		// what we've just done may have altered the body/joint tag values.
		// we must make sure that these tags are nonzero.
		// also make sure all bodies are in the enabled state.
		int i;
		for (i = 0; i < bcount; i++)
		{
			body[i]->tag = 1;
			body[i]->flags &= ~dxBodyDisabled;
		}
		for (i = 0; i < jcount; i++)
			joint[i]->tag = 1;
		
		tbcount += bcount;
		tjcount += jcount;
	}
	

}
Exemple #4
0
// sorts out islands,
// cllocates array for island information into arrays: body[nj], joint[nb], islandsizes[2*nb]
//   context->SavePreallocations(islandcount, islandsizes, body, joint,islandreqs);
// and put into context
//
static size_t BuildIslandsAndEstimateStepperMemoryRequirements(dxWorldProcessContext *context,
  dxWorld *world, dReal stepsize, dmemestimate_fn_t stepperestimate)
{
  const int sizeelements = 2;
  size_t maxreq = 0;

  // handle auto-disabling of bodies
  dInternalHandleAutoDisabling (world,stepsize);

  int nb = world->nb, nj = world->nj;
  // Make array for island body/joint counts
  int *islandsizes = context->AllocateArray<int>(2 * nb);
  int *sizescurr;
  // an array to save all islandreqs for each thread
  size_t *islandreqs = context->AllocateArray<size_t>(nb);
  size_t *islandreqscurr;

  // make arrays for body and joint lists (for a single island) to go into
  dxBody **body = context->AllocateArray<dxBody *>(nb);  // allocates a block of pointers and get back a pointer to first element
  dxJoint **joint = context->AllocateArray<dxJoint *>(nj);  // allocates a block of pointers and get back a pointer to first element

  BEGIN_STATE_SAVE(context, stackstate) {
    // stack is used to hold untagged bodies when traversing through all the joint-linked bodies.
    // at the end, all the bodies in the stack are popped back out into the island.
    //
    // allocate a stack of UNVISITED BODIES in the island. the maximum size of
    // the stack can be the lesser of the number of bodies or joints, because
    // new bodies are only ever added to the stack by going through untagged
    // joints. all the bodies in the stack must be tagged!
    int stackalloc = (nj < nb) ? nj : nb;
    dxBody **stack = context->AllocateArray<dxBody *>(stackalloc);  // a body stack

    {
      // set all body/joint island_tags to 0
      for (dxBody *b=world->firstbody; b; b=(dxBody*)b->next) b->island_tag = 0;
      for (dxJoint *j=world->firstjoint; j; j=(dxJoint*)j->next) j->island_tag = 0;
    }

    //int island_count = 0;
    sizescurr = islandsizes;
    islandreqscurr = islandreqs;
    dxBody **bodystart = body;
    dxJoint **jointstart = joint;
    // loop through all body, tag each one as it is processed
    // every step in this for loop is one island
    for (dxBody *bb=world->firstbody; bb; bb=(dxBody*)bb->next) {
      // get bb = the next enabled, untagged body, and tag it
      if (!bb->island_tag) {
        if (!(bb->flags & dxBodyDisabled)) {
          bb->island_tag = 1;

          dxBody **bodycurr = bodystart;
          dxJoint **jointcurr = jointstart;

          // tag all bodies and joints starting from bb.
          *bodycurr++ = bb;

          int stacksize = 0;
          dxBody *b = bb;

          while (true) {
            // traverse and island_tag all body's joints, add untagged connected bodies
            // to stack
            for (dxJointNode *n=b->firstjoint; n; n=n->next) {
              dxJoint *njoint = n->joint;
              if (!njoint->island_tag) {
                if (njoint->isEnabled()) {
                  njoint->island_tag = 1;
                  *jointcurr++ = njoint;

                  dxBody *nbody = n->body;
                  // Body disabled flag is not checked here. This is how auto-enable works.
                  if (nbody && nbody->island_tag <= 0) {
                    nbody->island_tag = 1;
                    // Make sure all bodies are in the enabled state.
                    nbody->flags &= ~dxBodyDisabled;
                    stack[stacksize++] = nbody;
                  }
                } else {
                  njoint->tag = -1; // Used in Step to prevent search over disabled joints (not needed for QuickStep so far)
                }
              }
            }
            dIASSERT(stacksize <= world->nb);
            dIASSERT(stacksize <= world->nj);

            if (stacksize == 0) {
              break;
            }

            b = stack[--stacksize];  // pop body off stack
            *bodycurr++ = b;  // put body on body list
          }

          int bcount = bodycurr - bodystart;
          int jcount = jointcurr - jointstart;
          sizescurr[0] = bcount;
          sizescurr[1] = jcount;
          sizescurr += sizeelements;

          // save individual islandreq for each island separately
          *islandreqscurr = stepperestimate(bodystart, bcount, jointstart, jcount);
          maxreq = (maxreq > *islandreqscurr) ? maxreq : *islandreqscurr;
          //printf("island %d complete, stepper  %d maxreq %d \n",island_count++,*islandreqscurr, maxreq);
          islandreqscurr += 1;

          bodystart = bodycurr;
          jointstart = jointcurr;
        } else {
          bb->island_tag = -1; // Not used so far (assigned to retain consistency with joints)
        }
      }
    }
  } END_STATE_SAVE(context, stackstate);  // restores contex pointer m_pAllocCurrent back to what it was before this block