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; }
/** * @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; } }
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; }
/***** * 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"); }