Example #1
0
MetricAnIso::MetricAnIso( Real8  a,const  MetricAnIso ma,
			  Real8  b,const  MetricAnIso mb)
{ 
  MetricAnIso mab(a*ma.a11+b*mb.a11,a*ma.a21+b*mb.a21,a*ma.a22+b*mb.a22);
  MatVVP2x2 vab(mab);
  
  R2 v1(vab.v.x,vab.v.y);
  R2 v2(-v1.y,v1.x);
  

  Real8 h1 = a / ma(v1) + b / mb(v1);
  Real8 h2 = a / ma(v2) + b / mb(v2);
  vab.lambda1 =  1 / (h1*h1);
  vab.lambda2 =  1 / (h2*h2);
  *this = vab;
}
Example #2
0
MetricAnIso::MetricAnIso(const Real8  a[3],const  MetricAnIso m0,
			 const  MetricAnIso m1,const  MetricAnIso m2 )
{
  MetricAnIso mab(a[0]*m0.a11 + a[1]*m1.a11 + a[2]*m2.a11,
		  a[0]*m0.a21 + a[1]*m1.a21 + a[2]*m2.a21,
		  a[0]*m0.a22 + a[1]*m1.a22 + a[2]*m2.a22);
  
  MatVVP2x2 vab(mab);
 
  R2 v1(vab.v.x,vab.v.y);
  R2 v2(-v1.y,v1.x);
  
  Real8 h1 = a[0] / m0(v1) + a[1] / m1(v1) + a[2] / m2(v1);
  Real8 h2 = a[0] / m0(v2) + a[1] / m1(v2) + a[2] / m2(v2);

  vab.lambda1 =  1 / (h1*h1);
  vab.lambda2 =  1 / (h2*h2);
  *this = vab;
}
Example #3
0
// Doc in parent
void
SoVRMLIndexedFaceSet::GLRender(SoGLRenderAction * action)
{
  if (this->coordIndex.getNum() < 3 || this->coord.getValue() == NULL) return;
  SoState * state = action->getState();

  state->push();
  // update state with coordinates, normals and texture information
  SoVRMLVertexShape::GLRender(action);

  if (!this->shouldGLRender(action)) { 
    state->pop();
    return;
  }

  this->setupShapeHints(state, this->ccw.getValue(), this->solid.getValue());

  Binding mbind = this->findMaterialBinding(state);
  Binding nbind = this->findNormalBinding(state);

  const SoCoordinateElement * coords;
  const SbVec3f * normals;
  const int32_t * cindices;
  int numindices;
  const int32_t * nindices;
  const int32_t * tindices;
  const int32_t * mindices;
  SbBool doTextures;
  SbBool normalCacheUsed;
  SoMaterialBundle mb(action);
  SoTextureCoordinateBundle tb(action, TRUE, FALSE);
  doTextures = tb.needCoordinates();

  SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();

  this->getVertexData(state, coords, normals, cindices,
                      nindices, tindices, mindices, numindices,
                      sendNormals, normalCacheUsed);

  if (!sendNormals) {
    nbind = OVERALL;
    normals = NULL;
    nindices = NULL;
  }
  else if (nbind == OVERALL) {
    if (normals) glNormal3fv(normals[0].getValue());
    else glNormal3f(0.0f, 0.0f, 1.0f);
  }
  else if (normalCacheUsed && nbind == PER_VERTEX) {
    nbind = PER_VERTEX_INDEXED;
  }
  else if (normalCacheUsed && nbind == PER_FACE_INDEXED) {
    nbind = PER_FACE;
  }

  if (mbind == PER_VERTEX) {
    mbind = PER_VERTEX_INDEXED;
    mindices = cindices;
  }
  if (nbind == PER_VERTEX) {
    nbind = PER_VERTEX_INDEXED;
    nindices = cindices;
  }

  Binding tbind = NONE;
  if (doTextures) {
    if (tb.isFunction() && !tb.needIndices()) {
      tbind = NONE;
      tindices = NULL;
    }
    else {
      tbind = PER_VERTEX_INDEXED;
      if (tindices == NULL) tindices = cindices;
    }
  }
  SbBool convexcacheused = FALSE;

  if (this->useConvexCache(action, normals, nindices, normalCacheUsed)) {
    cindices = PRIVATE(this)->convexCache->getCoordIndices();
    numindices = PRIVATE(this)->convexCache->getNumCoordIndices();
    mindices = PRIVATE(this)->convexCache->getMaterialIndices();
    nindices = PRIVATE(this)->convexCache->getNormalIndices();
    tindices = PRIVATE(this)->convexCache->getTexIndices();

    if (mbind == PER_VERTEX) mbind = PER_VERTEX_INDEXED;
    else if (mbind == PER_FACE) mbind = PER_FACE_INDEXED;
    if (nbind == PER_VERTEX) nbind = PER_VERTEX_INDEXED;
    else if (nbind == PER_FACE) nbind = PER_FACE_INDEXED;

    if (tbind != NONE) tbind = PER_VERTEX_INDEXED;
    convexcacheused = TRUE;
  }

  mb.sendFirst(); // make sure we have the correct material

  SoGLLazyElement * lelem = NULL;
  const uint32_t contextid = action->getCacheContext();

  SbBool dova = 
    SoVBO::shouldRenderAsVertexArrays(state, contextid, numindices) &&
    !convexcacheused && !normalCacheUsed &&
    ((nbind == OVERALL) || ((nbind == PER_VERTEX_INDEXED) && ((nindices == cindices) || (nindices == NULL)))) &&
    ((tbind == NONE && !tb.needCoordinates()) || 
     ((tbind == PER_VERTEX_INDEXED) && ((tindices == cindices) || (tindices == NULL)))) &&
    ((mbind == NONE) || ((mbind == PER_VERTEX_INDEXED) && ((mindices == cindices) || (mindices == NULL)))) &&
    SoGLDriverDatabase::isSupported(sogl_glue_instance(state), SO_GL_VERTEX_ARRAY);

  const SoGLVBOElement * vboelem = SoGLVBOElement::getInstance(state);
  SoVBO * colorvbo = NULL;

  if (dova && (mbind != OVERALL)) {
    dova = FALSE;
    if ((mbind == PER_VERTEX_INDEXED) && ((mindices == cindices) || (mindices == NULL))) {
      lelem = (SoGLLazyElement*) SoLazyElement::getInstance(state);
      colorvbo = vboelem->getColorVBO();
      if (colorvbo) dova = TRUE;
      else {
        // we might be able to do VA-rendering, but need to check the
        // diffuse color type first.
        if (!lelem->isPacked() && lelem->getNumTransparencies() <= 1) {
          dova = TRUE;
        }
      }
    }
  }
  SbBool didrenderasvbo = FALSE;
  if (dova) {
    SbBool dovbo = this->startVertexArray(action,
                                          coords,
                                          (nbind != OVERALL) ? normals : NULL,
                                          doTextures,
                                          mbind != OVERALL);
    didrenderasvbo = dovbo;
    LOCK_VAINDEXER(this);
    if (PRIVATE(this)->vaindexer == NULL) {
      SoVertexArrayIndexer * indexer = new SoVertexArrayIndexer;
      int i = 0;
      while (i < numindices) {
        int cnt = 0;
        while (i + cnt < numindices && cindices[i+cnt] >= 0) cnt++;
        
        switch (cnt) {
        case 3:
          indexer->addTriangle(cindices[i],cindices[i+1], cindices[i+2]);
          break;
        case 4:
          indexer->addQuad(cindices[i],cindices[i+1],cindices[i+2],cindices[i+3]);
          break;
        default:
          if (cnt > 4) {
            indexer->beginTarget(GL_POLYGON);
            for (int j = 0; j < cnt; j++) {
              indexer->targetVertex(GL_POLYGON, cindices[i+j]);
            }
            indexer->endTarget(GL_POLYGON);
          }
        }
        i += cnt + 1;
      }
      indexer->close();
      if (indexer->getNumVertices()) {
        PRIVATE(this)->vaindexer = indexer;
      }
      else {
        delete indexer;
      }
#if 0
      fprintf(stderr,"XXX: create VRML VertexArrayIndexer: %d\n", indexer->getNumVertices());
#endif
    }

    if (PRIVATE(this)->vaindexer) {
      PRIVATE(this)->vaindexer->render(sogl_glue_instance(state), dovbo, contextid);
    }
    UNLOCK_VAINDEXER(this);
    this->finishVertexArray(action,
                            dovbo,
                            (nbind != OVERALL),
                            doTextures,
                            mbind != OVERALL);
  }
  else {
    SoVertexAttributeBundle vab(action, TRUE);
    SbBool doattribs = vab.doAttributes();

    SoVertexAttributeBindingElement::Binding attribbind = 
      SoVertexAttributeBindingElement::get(state);

    if (!doattribs) { 
      // for overall attribute binding we check for doattribs before
      // sending anything in SoGL::FaceSet::GLRender
      attribbind = SoVertexAttributeBindingElement::OVERALL;
    }

    sogl_render_faceset((SoGLCoordinateElement *)coords,
                        cindices,
                        numindices,
                        normals,
                        nindices,
                        &mb,
                        mindices,
                        &tb,
                        tindices,
                        &vab,
                        (int)nbind,
                        (int)mbind,
                        (int)attribbind,
                        doTextures ? 1 : 0,
                        doattribs ? 1 : 0);

  }
  if (normalCacheUsed) {
    this->readUnlockNormalCache();
  }

  if (convexcacheused) {
    PRIVATE(this)->readUnlockConvexCache();
  }

  // send approx number of triangles for autocache handling
  sogl_autocache_update(state, this->coordIndex.getNum() / 4, didrenderasvbo);

  state->pop();
}
Example #4
0
void World::update(float timeStep)
{
    for(BodyList::iterator it = m_bodies.begin(); it != m_bodies.end(); ++it){
        if(!(*it)->getBodyDef().isStatic()){
            (*it)->acceleration(m_gravitation*timeStep);
            (*it)->update(timeStep);
        }
    }


    for(BodyList::iterator it = m_bodies.begin(); it != m_bodies.end(); ++it){
        BodyList::iterator ith = it;
        ith++;
        for(BodyList::iterator it2 = ith; it2 != m_bodies.end(); ++it2){
            if(!((*it)->getBodyDef().isStatic()) or !((*it2)->getBodyDef().isStatic())){
                if((*it)->getShape()->collide((*it2)->getShape().get())){
                    Polygon *p1 = static_cast<Polygon *>((*it)->getShape().get());
                    Polygon *p2 = static_cast<Polygon *>((*it2)->getShape().get());

                    bool b = true;
                    Line cl;

                    Vector2f point1 = p1->getTransformedPoint(p1->getNumberOfPoints()-1);
                    Vector2f point2 = p2->getTransformedPoint(p2->getNumberOfPoints()-1);

                    for(size_t i = 0; i < p1->getNumberOfPoints(); ++i){
                        Line line1(p1->getTransformedPoint(i), point1-p1->getTransformedPoint(i));
                        point1 = p1->getTransformedPoint(i);
                        for(size_t j = 0; j < p2->getNumberOfPoints(); ++j){
                            Line line2(p2->getTransformedPoint(j), point2-p2->getTransformedPoint(j));
                            point2 = p2->getTransformedPoint(j);

                            float t1 = line1.intersects(line2);
                            float t2 = line2.intersects(line1);

                            if(0.f < t1 and t1 < 1.f and 0.f < t2 and t2 < 1.f){
                                Vector2f vec = line1.getPoint() + t1 * line1.getDirectionVector();
                                if(b){
                                    cl.setPoint(vec);
                                    b = false;
                                } else {
                                    cl.setDirectionVector(vec - cl.getPoint());
                                }
                            }
                        }
                    }
                    Vector2f n = cl.getDirectionVector().normal();
                    //n.normalize();
                    Vector2f p = cl.getPoint()+(cl.getDirectionVector()/2.f);
                    Body::Ptr b1 = (*it);
                    Body::Ptr b2 = (*it2);

                    mx::Vector2f r1(p - b1->getShape()->getPosition());
                    mx::Vector2f r2(p - b2->getShape()->getPosition());

                    mx::Vector2f rap = r1.normal();
                    mx::Vector2f rbp = r2.normal();

                    float rapn = dot(rap, n);
                    float rbpn = dot(rbp, n);

                    mx::Vector2f vp1(b1->getVelocity()+b1->getAngularVelocity()*rap);
                    mx::Vector2f vp2(b2->getVelocity()+b2->getAngularVelocity()*rbp);
                    mx::Vector2f vab(vp2 - vp1);

                    float M1Inv = 0;
                    float M2Inv = 0;
                    float I1Inv = 0;
                    float I2Inv = 0;

                    if(!b1->getBodyDef().isStatic()){
                        M1Inv = 1.f / b1->getBodyDef().getMass();
                        I1Inv = 1.f / b1->getBodyDef().getMomentOfInertia();
                    }
                    if(!b2->getBodyDef().isStatic()){
                        M2Inv = 1.f / b2->getBodyDef().getMass();
                        I2Inv = 1.f / b2->getBodyDef().getMomentOfInertia();
                    }


                    float j = -(1+(b1->getBodyDef().getElasticity()+b2->getBodyDef().getElasticity())/2.f) * dot(vab, n);
                    j /= dot(n, n)*(M1Inv+M2Inv) + rapn*rapn*I1Inv + rbpn*rbpn*I2Inv;

                    b1->acceleration(-(j*M1Inv) * n);
                    b2->acceleration( (j*M2Inv) * n);

                    b1->angularAcceleration(-j*I1Inv * rapn);
                    b2->angularAcceleration( j*I2Inv * rbpn);

                    Shape::Ptr s1 = b1->getShape();
                    Shape::Ptr s2 = b2->getShape();

                    mx::Vector2f MTD = s1->MTD(s2.get());

                    float MInv = M1Inv + M2Inv;

                    s1->setPosition(s1->getPosition()+MTD*(M1Inv/MInv));
                    s2->setPosition(s2->getPosition()-MTD*(M2Inv/MInv));
                }
            }
        }
    }
}