ShadowVolumeBSP::SVPoly * ShadowVolumeBSP::copyPoly(SVPoly * src)
{
    SVPoly * poly = createPoly();
    dMemcpy(poly, src, sizeof(SVPoly));

    poly->mTarget = 0;
    poly->mNext = 0;

    return(poly);
}
cpShape *cpSpaceSerializer::createShape(TiXmlElement *elm)
{
	cpShape *shape;
	
	const char* type = elm->Attribute("type");
	
	if (stringEquals(type, "circle"))
		shape = createCircle(elm);
	else if (stringEquals(type, "segment"))
		shape = createSegment(elm);
	else if (stringEquals(type, "poly"))
		shape = createPoly(elm);
	else
		return NULL;
	
	CPSS_ID id = createValue<CPSS_ID>("id", elm);
    _shapeMap[id] = shape;
	
	shape->sensor = createValue<int>("sensor", elm);
	shape->e = createValue<cpFloat>("e", elm);
	shape->u = createValue<cpFloat>("u", elm);
	shape->surface_v = createPoint("surface_v", elm);
	shape->collision_type = createValue<cpCollisionType>("collision_type", elm);
	shape->group = createValue<cpGroup>("group", elm);
	shape->layers = createValue<cpLayers>("layers", elm);
	
	if (delegate)
	{
		if (!delegate->reading(shape, id))
		{
            if (shape->body != _space->staticBody)
                cpBodyFree(shape->body);

            cpShapeFree(shape);
			shape = NULL;
		}
	}
	return shape;
}
Exemple #3
0
/** 
 * @brief the three points in indices are Different from each other
 * 
 * @param subpoly 
 * @param indices 
 * @param loc 
 * @param dim 
 * @param coefs 
 * @param ans 
 * 
 * @return 
 */
static BOOL checkThreeP(const SubPoly* subpoly, const indice_t* indices,
                        const int* loc, const int dim, const coef_t* coefs,
                        PointList* ans) {
  int i;
  int VA, VB, VM;
  indice_t key[dim];
  if (isSameLine(indices, loc, 3, dim)) { /* on a same line */
    if (coefs[loc[0]] < 0) {
      if (coefs[loc[1]] < 0 || coefs[loc[2]] < 0) return NOSOS;
    } else {
      if (coefs[loc[1]] < 0 && coefs[loc[2]] < 0) return NOSOS;
    }
    i = 0;
    while (indices[loc[0] * dim + i] == indices[loc[1] * dim + i] &&
           indices[loc[1] * dim + i] == indices[loc[2] * dim + i])
      i++;

    int AB = abs(indices[loc[0] * dim + i] - indices[loc[1] * dim + i]);
    int BC = abs(indices[loc[1] * dim + i] - indices[loc[2] * dim + i]);
    int AC = abs(indices[loc[0] * dim + i] - indices[loc[2] * dim + i]);

    if (AC > AB && AC > BC) { /* A C are vertex  */
      VA = 0;
      VB = 2;
      VM = 1;

    } else if (AB > AC && AB > BC) { /* A B are vertex  */
      VA = 0;
      VB = 1;
      VM = 2;

    } else { /* B C are vertex */
      VA = 1;
      VB = 2;
      VM = 0;
    }

    if (coefs[loc[VA]] < 0 || coefs[loc[VB]] < 0) return NOSOS;
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[VA] * dim + i] & 1 == 1) return NOSOS;
    }

    for (i = 0; i < dim; i += 1) {
      if (indices[loc[VB] * dim + i] & 1 == 1) return NOSOS;
    }



    if (coefs[loc[VM]] < 0) {
      if (fabs(coefs[loc[VM]]) > coefs[loc[VA]] + coefs[loc[VB]]) return NOSOS;
    } else {
      for (i = 0; i < dim; i += 1) {
        if (indices[loc[VM] * dim + i] & 1 == 1) break;
      }
      if (i == dim) {
        if (NULL != ans) {
          Poly* p = createPoly();
          polyChangeVarId(p, subpoly->poly->varId);

          for (i = 0; i < dim; i += 1) {
            key[i] = indices[loc[0] * dim + i] / 2;
          }
          internal_addTerm(p, key, sqrtf(coefs[loc[0]]));
          push_back_L(ans, p);

          Poly* p1 = createPoly();
          polyChangeVarId(p1, subpoly->poly->varId);

          for (i = 0; i < dim; i += 1) {
            key[i] = indices[loc[1] * dim + i] / 2;
          }
          internal_addTerm(p1, key, sqrtf(coefs[loc[1]]));
          push_back_L(ans, p1);

          Poly* p2 = createPoly();
          polyChangeVarId(p2, subpoly->poly->varId);

          for (i = 0; i < dim; i += 1) {
            key[i] = indices[loc[2] * dim + i] / 2;
          }
          internal_addTerm(p2, key, sqrtf(coefs[loc[2]]));
          push_back_L(ans, p2);
        }

        return EXACTLY_SOS;
      } else if (coefs[loc[VM]] > coefs[loc[VA]] + coefs[loc[VB]])
        return NOSOS;
    }
    return UNHNOW;
  } else {
    if (coefs[loc[0]] < 0 || coefs[loc[1]] < 0 || coefs[loc[2]] < 0)
      return NOSOS;
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[0] * dim + i] & 1 == 1) return NOSOS;
    }
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[1] * dim + i] & 1 == 1) return NOSOS;
    }
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[2] * dim + i] & 1 == 1) return NOSOS;
    }
    if (NULL != ans) {
      Poly* p = createPoly();
      polyChangeVarId(p, subpoly->poly->varId);

      for (i = 0; i < dim; i += 1) {
        key[i] = indices[loc[0] * dim + i] / 2;
      }
      internal_addTerm(p, key, sqrtf(coefs[loc[i]]));
      push_back_L(ans, p);

      Poly* p1 = createPoly();
      polyChangeVarId(p1, subpoly->poly->varId);

      for (i = 0; i < dim; i += 1) {
        key[i] = indices[loc[1] * dim + i] / 2;
      }
      internal_addTerm(p1, key, sqrtf(coefs[loc[i]]));
      push_back_L(ans, p1);

      Poly* p2 = createPoly();
      polyChangeVarId(p2, subpoly->poly->varId);

      for (i = 0; i < dim; i += 1) {
        key[i] = indices[loc[2] * dim + i] / 2;
      }
      internal_addTerm(p2, key, sqrtf(coefs[loc[i]]));
      push_back_L(ans, p2);
    }

    return EXACTLY_SOS;
  }
}
Exemple #4
0
int easyCheck(const SubPoly* subpoly, PointList* ans) {
  const int size = subpoly->size;
  int* loc = subpoly->locs;

  indice_t* indices = subpoly->poly->indices;
  coef_t* pcoefs = subpoly->poly->coef;

  int dim = getvarNum(subpoly->poly->varId);

  indice_t key[dim];

  int coefs[dim];
  char convexSurf[size];
  char maxPoint[size];
  int i, j, k;
  int coefDomain = 1;
  int maxSum = 0;
  long int tempSum;
  int number = 0;
  int first = 0;
  int second = 0;
  double planeSum;
  memset(convexSurf, 0, size * sizeof(char));

  if (size == 1) {
    if (pcoefs[loc[0]] < 0) return NOSOS;
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[0] * dim + i] & 1 == 1) return NOSOS;
      key[i] = indices[loc[0] * dim + i] / 2;
    }
    if (NULL != ans) {
      Poly* p = createPoly();
      polyChangeVarId(p, subpoly->poly->varId);
      internal_addTerm(p, key, sqrtf(pcoefs[loc[0]]));
      push_back_L(ans, p);
    }

    return EXACTLY_SOS;
  } else if (size == 2) {
    if (pcoefs[loc[0]] < 0 || pcoefs[loc[1]] < 0) return NOSOS;
    for (i = 0; i < dim; i += 1) {
      if (indices[loc[0] * dim + i] & 1 == 1) return NOSOS;
    }
    for (i = 0; i < dim; i += 1) {
      if (indices[dim * loc[1] + i] & 1 == 1) return NOSOS;
    }
    if (NULL != ans) {
      Poly* p = createPoly();
      polyChangeVarId(p, subpoly->poly->varId);
      for (i = 0; i < dim; i += 1) {
        key[i] = indices[loc[0] * dim + i] / 2;
      }
      internal_addTerm(p, key, sqrtf(pcoefs[loc[0]]));

      push_back_L(ans, p);

      Poly* p1 = createPoly();
      polyChangeVarId(p1, subpoly->poly->varId);

      for (i = 0; i < dim; i += 1) {
        key[i] = indices[loc[1] * dim + i] / 2;
      }
      internal_addTerm(p1, key, sqrtf(pcoefs[loc[1]]));
      push_back_L(ans, p1);
    }

    return EXACTLY_SOS;
  } else if (size == 3) {
    return checkThreeP(subpoly, indices, loc, dim, pcoefs, ans);
  }

  for (i = 0; i < size; i += 1) {
    if (pcoefs[loc[i]] < 0) break;

    for (k = 0; k < dim; k += 1) {
      if (indices[loc[i] * dim + k] & 1 == 1) break;
    }
    if (k != dim) break;
  }
  if (i == size) {
    if (NULL != ans)
      for (i = 0; i < size; i += 1) {
        Poly* p = createPoly();
        polyChangeVarId(p, subpoly->poly->varId);

        for (k = 0; k < dim; k += 1) {
          key[k] = indices[loc[i] * dim + k] / 2;
        }
        internal_addTerm(p, key, sqrtf(pcoefs[loc[i]]));
        push_back_L(ans, p);
      }

    return EXACTLY_SOS;
  }

  int checkTime = (size)*dim * dim;

  for (i = 0; i < checkTime; i += 1) {
    memset(maxPoint, 0, size * sizeof(char));
    number = 0;
    coefDomain = sqrt(i) / (2 * size) + 1;

    maxSum = 0;
    while (0 == maxSum) {
      for (j = 0; j < dim; j += 1) {
        coefs[j] = rand() % (2 * coefDomain + 1) - coefDomain;
        if (coefs[j] != 0) maxSum = 1;
      }
    }
    maxSum = 0;

    for (k = 0; k < dim; k += 1) {
      maxSum += coefs[k] * indices[loc[0] * dim + k];
    }

    maxPoint[0] = 1;
    number = 1;
    first = 0;

    for (k = 1; k < size; k += 1) {

      tempSum = 0;

      for (j = 0; j < dim; j += 1) {
        tempSum += coefs[j] * indices[loc[k] * dim + j];
      }
      if (tempSum > maxSum) {
        maxSum = tempSum;
        memset(maxPoint, 0, k * sizeof(char));
        maxPoint[k] = 1;
        number = 1;
        first = k;
      } else if (tempSum == maxSum) {
        maxPoint[k] = 1;
        number++;
        second = k;
      }
    }
    if (number == 1) {
      convexSurf[first] = 1;
      if (pcoefs[loc[first]] < -1e-6) return NOSOS;
      for (j = 0; j < dim; j += 1) {
        if (indices[loc[first] * dim + j] & 1 == 1) return NOSOS;
      }
    } else if (number == 2) {
      convexSurf[first] = 1;
      if (pcoefs[loc[first]] < -1e-6) return NOSOS;
      for (j = 0; j < dim; j += 1) {
        if (indices[loc[first] * dim + j] & 1 == 1) return NOSOS;
      }
      convexSurf[second] = 1;
      if (pcoefs[loc[second]] < -1e-6) return NOSOS;
      for (j = 0; j < dim; j += 1) {
        if (indices[loc[second] * dim + j] & 1 == 1) return NOSOS;
      }
    } else {
      planeSum = 0;
      for (k = 0; k < size; k += 1) {
        if (1 == maxPoint[k]) {
          convexSurf[k] = 1;
          planeSum += pcoefs[loc[k]];
        }
      }
      if (planeSum < -1e-6) return NOSOS;
    }
  }
  number = 0;
  for (i = 0; i < size; i += 1) {
    if (0 == convexSurf[i]) number++;
  }
  double base = 0.1;
  if ((number + 0.0) / size < base)
    return CONVEX_POLY;
  else
    return UNHNOW;
}
Exemple #5
0
/*****
* Name: 		_XmHTMLAddAreaToMap
* Return Type: 	void
* Description: 	adds the given area specification to the given imagemap
* In: 
*	map:		XmHTMLImageMap
*	object:		raw area data
* Returns:
*	nothing
*****/
void
_XmHTMLAddAreaToMap(XmHTMLWidget html, XmHTMLImageMap *map, 
	XmHTMLObject *object)
{
	static mapArea *area;
	mapArea *tmp;
	String chPtr;

	/* sanity */
	if(map == NULL || object->attributes == NULL)
		return;

	area = (mapArea*)malloc(sizeof(mapArea));

	(void)memset(area, 0, sizeof(mapArea));

	area->url = _XmHTMLTagGetValue(object->attributes, "href");
	area->alt = _XmHTMLTagGetValue(object->attributes, "alt");
	area->nohref = _XmHTMLTagCheck(object->attributes, "nohref");

	chPtr = _XmHTMLTagGetValue(object->attributes, "shape");

	/* get specified coordinates */
	area->coords = getCoordinates(object->attributes, &area->ncoords);

	/*
	* No shape given, try to figure it out using the number of specified
	* coordinates
	*/
	if(chPtr == NULL)
	{
		switch(area->ncoords)
		{
			case 0:
				/* no coords given => default area */
				area->shape = MAP_DEFAULT;
				break;
			case 3:
				/* 3 coords => circle */
				area->shape = MAP_CIRCLE;
				break;
			case 4:
				/* 4 coords => assume rectangle */
				area->shape = MAP_RECT;
				break;
			default:
				/* assume poly */
				area->shape = MAP_POLY;
		}
	}
	else
	{
		switch(tolower(chPtr[0]))
		{
			case 'c':
				area->shape = MAP_CIRCLE;
				break;
			case 'r':
				area->shape = MAP_RECT;
				break;
			case 'p':
				area->shape = MAP_POLY;
				break;
			default:
				area->shape = MAP_DEFAULT;
		}
		free(chPtr);
	}

	/* check if all coordinates specs are valid for the given shape */
	switch(area->shape)
	{
		case MAP_RECT:
			/* too bad if coords are bad */
			if(area->ncoords != 4)
			{
				_XmHTMLWarning(__WFUNC__(html, "_XmHTMLAddAreaToImagemap"),
					XMHTML_MSG_81, area->ncoords, object->line);
				/* too many coordinates, drop the excessive ones */
				if(area->ncoords > 4)
					area->ncoords = 4;
				else
				{
					/*****
					* Less than required, do a complex rescan of the
					* attributes (any sequence of non-digits is considered
					* a separator).
					*****/
					free(area->coords);
					area->coords = getComplexCoordinates(object->attributes,
						&area->ncoords);
					/* too many coordinates, drop the excessive ones */
					if(area->ncoords > 4)
						area->ncoords = 4;
					else
					{
						String chPtr = _XmHTMLTagGetValue(object->attributes,
										"coords");
						_XmHTMLWarning(__WFUNC__(html,
							"_XmHTMLAddAreaToImagemap"), XMHTML_MSG_82, chPtr);
						free(chPtr);
						deleteArea(area);
						return;
					}
				}
			}
			break;
		case MAP_CIRCLE:
			/* too bad if coords are bad */
			if(area->ncoords != 3)
			{
				_XmHTMLWarning(__WFUNC__(html,
					"_XmHTMLAddAreaToImagemap"), XMHTML_MSG_83,
					area->ncoords, object->line);
				deleteArea(area);
				return;
			}
			break;
		case MAP_POLY:
			if(!area->coords)
			{
				_XmHTMLWarning(__WFUNC__(html, "_XmHTMLAddAreaToImagemap"),
					XMHTML_MSG_84, area->ncoords, object->line);
				deleteArea(area);
				return;
			}
			if(area->ncoords % 2)
			{
				_XmHTMLWarning(__WFUNC__(html, "_XmHTMLAddAreaToImagemap"),
					XMHTML_MSG_85, area->ncoords, object->line);
				area->ncoords--;
			}
			area->region = createPoly(area->ncoords, area->coords);
			break;
		default:
			break;
	}

	/* gets automagically added to the list of anchors for this widget */
	if(!area->nohref)
		area->anchor = _XmHTMLNewAnchor(html, object);

	/* add this area to the list of areas for this imagemap */
	if(map->areas == NULL)
	{
		map->nareas = 1;
		map->areas = area;
		return;
	}
	for(tmp = map->areas; tmp != NULL && tmp->next != NULL ; tmp = tmp->next);
	map->nareas++;
	tmp->next = area;

	_XmHTMLDebug(10, ("map.c: _XmHTMLAddAreaToMap, stored href %s, map now "
		"contains %i areas.\n", area->url, map->nareas));
}
void ShadowVolumeBSP::splitPoly(SVPoly * poly, const PlaneF & plane, SVPoly ** front, SVPoly ** back)
{
    PlaneF::Side sides[SVPoly::MaxWinding];

    U32 i;
    for(i = 0; i < poly->mWindingCount; i++)
        sides[i] = plane.whichSide(poly->mWinding[i]);

    // create the polys
    (*front) = createPoly();
    (*back) = createPoly();

    // copy the info
    (*front)->mWindingCount = (*back)->mWindingCount = 0;
    (*front)->mPlane = (*back)->mPlane = poly->mPlane;
    (*front)->mTarget = (*back)->mTarget = poly->mTarget;
    (*front)->mSurfaceInfo = (*back)->mSurfaceInfo = poly->mSurfaceInfo;
    (*front)->mShadowVolume = (*back)->mShadowVolume = poly->mShadowVolume;

    //
    for(i = 0; i < poly->mWindingCount; i++)
    {
        U32 j = (i+1) % poly->mWindingCount;

        if(sides[i] == PlaneF::On)
        {
            (*front)->mWinding[(*front)->mWindingCount++] = poly->mWinding[i];
            (*back)->mWinding[(*back)->mWindingCount++] = poly->mWinding[i];
        }
        else if(sides[i] == PlaneF::Front)
        {
            (*front)->mWinding[(*front)->mWindingCount++] = poly->mWinding[i];

            if(sides[j] == PlaneF::Back)
            {
                const Point3F & a = poly->mWinding[i];
                const Point3F & b = poly->mWinding[j];

                F32 t = plane.intersect(a, b);
                AssertFatal(t >=0 && t <= 1, "ShadowVolumeBSP::splitPoly - bad plane intersection");

                Point3F pos;
                pos.interpolate(a, b, t);

                //
                (*front)->mWinding[(*front)->mWindingCount++] =
                    (*back)->mWinding[(*back)->mWindingCount++] = pos;
            }
        }
        else if(sides[i] == PlaneF::Back)
        {
            (*back)->mWinding[(*back)->mWindingCount++] = poly->mWinding[i];

            if(sides[j] == PlaneF::Front)
            {
                const Point3F & a = poly->mWinding[i];
                const Point3F & b = poly->mWinding[j];

                F32 t = plane.intersect(a, b);
                AssertFatal(t >=0 && t <= 1, "ShadowVolumeBSP::splitPoly - bad plane intersection");

                Point3F pos;
                pos.interpolate(a, b, t);

                (*front)->mWinding[(*front)->mWindingCount++] =
                    (*back)->mWinding[(*back)->mWindingCount++] = pos;
            }
        }
    }

    AssertFatal((*front)->mWindingCount && (*back)->mWindingCount, "ShadowVolume::split - invalid split");
}