//-*****************************************************************************
void meshUnderXformOut( const std::string &iName )
{
    OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), iName );

    TimeSamplingPtr ts( new TimeSampling( 1.0 / 24.0, 0.0 ) );

    OXform xfobj( archive.getTop(), "xf", ts );

    OPolyMesh meshobj( xfobj, "mesh", ts );

    OPolyMeshSchema::Sample mesh_samp(
        V3fArraySample( ( const V3f * )g_verts, g_numVerts ),
        Int32ArraySample( g_indices, g_numIndices ),
        Int32ArraySample( g_counts, g_numCounts ) );

    XformSample xf_samp;
    XformOp rotOp( kRotateYOperation );

    Box3d childBounds;
    childBounds.makeEmpty();
    childBounds.extendBy( V3d( 1.0, 1.0, 1.0 ) );
    childBounds.extendBy( V3d( -1.0, -1.0, -1.0 ) );

    xf_samp.setChildBounds( childBounds );

    double rotation = 0.0;

    for ( std::size_t i = 0 ; i < 100 ; ++i )
    {
        xf_samp.addOp( rotOp, rotation );
        xfobj.getSchema().set( xf_samp );
        meshobj.getSchema().set( mesh_samp );
        rotation += 30.0;
    }
}
Ejemplo n.º 2
0
Imath::Box3d AlembicInput::boundAtTime( double time ) const
{
	if( hasStoredBound() )
	{
		size_t index0, index1;
		double lerpFactor = sampleIntervalAtTime( time, index0, index1 );
		if( index0 == index1 )
		{
			return boundAtSample( index0 );
		}
		else
		{
			Box3d bound0 = boundAtSample( index0 );
			Box3d bound1 = boundAtSample( index1 );		
			Box3d result;
			result.min = lerp( bound0.min, bound1.min, lerpFactor );	
			result.max = lerp( bound0.max, bound1.max, lerpFactor );
			return result;
		}
	}
	else
	{
		Box3d result;
		for( size_t i=0, n=numChildren(); i<n; i++ )
		{
			AlembicInputPtr c = child( i );
			Box3d childBound = c->boundAtTime( time );
			childBound = Imath::transform( childBound, c->transformAtTime( time ) );
			result.extendBy( childBound );
		}
		return result;
	}
}
Ejemplo n.º 3
0
  int AdFront2 :: AddLine (int pi1, int pi2,
                           const PointGeomInfo & gi1, const PointGeomInfo & gi2)
  {
    int minfn;
    int li;

    FrontPoint2 & p1 = points[pi1];
    FrontPoint2 & p2 = points[pi2];


    nfl++;

    p1.AddLine();
    p2.AddLine();

    minfn = min2 (p1.FrontNr(), p2.FrontNr());
    p1.DecFrontNr (minfn+1);
    p2.DecFrontNr (minfn+1);

    if (dellinel.Size() != 0)
      {
	li = dellinel.Last();
	dellinel.DeleteLast ();
	lines[li] = FrontLine (INDEX_2(pi1, pi2));
      }
    else
      {
	li = lines.Append(FrontLine (INDEX_2(pi1, pi2))) - 1;
      }

  
    if (!gi1.trignum || !gi2.trignum)
      {
	cout << "ERROR: in AdFront::AddLine, illegal geominfo" << endl;
      }
  
    lines[li].SetGeomInfo (gi1, gi2);

    Box3d lbox;
    lbox.SetPoint(p1.P());
    lbox.AddPoint(p2.P());

    linesearchtree.Insert (lbox.PMin(), lbox.PMax(), li);

    if (allflines)
      {
	if (allflines->Used (INDEX_2 (GetGlobalIndex (pi1), 
				      GetGlobalIndex (pi2))))
	  {
	    cerr << "ERROR Adfront2::AddLine: line exists" << endl;
	    (*testout) << "ERROR Adfront2::AddLine: line exists" << endl;
	  }

	allflines->Set (INDEX_2 (GetGlobalIndex (pi1), 
				 GetGlobalIndex (pi2)), 1);
      }

    return li;
  }
//-*****************************************************************************
//-*****************************************************************************
// WRITING OUT AN ANIMATED MESH
//
// Here we'll create an "Archive", which is Alembic's term for the actual
// file on disk containing all of the scene geometry. The Archive will contain
// a single animated Transform with a single static PolyMesh as its child.
//-*****************************************************************************
//-*****************************************************************************
void Example1_MeshOut()
{
    // Create an OArchive.
    // Like std::iostreams, we have a completely separate-but-parallel class
    // hierarchy for output and for input (OArchive, IArchive, and so on). This
    // maintains the important abstraction that Alembic is for storage,
    // representation, and archival. (as opposed to being a dynamic scene
    // manipulation framework).
    OArchive archive(

        // The hard link to the implementation.
        Alembic::AbcCoreHDF5::WriteArchive(),

        // The file name.
        // Because we're an OArchive, this is creating (or clobbering)
        // the archive with this filename.
        "polyMesh1.abc" );

    // Create a PolyMesh class.
    OPolyMesh meshyObj( OObject( archive, kTop ), "meshy" );
    OPolyMeshSchema &mesh = meshyObj.getSchema();

    // UVs and Normals use GeomParams, which can be written or read
    // as indexed or not, as you'd like.
    OV2fGeomParam::Sample uvsamp( V2fArraySample( (const V2f *)g_uvs,
                                                  g_numUVs ),
                                  kFacevaryingScope );
    // indexed normals
    ON3fGeomParam::Sample nsamp( N3fArraySample( (const N3f *)g_normals,
                                                 g_numNormals ),
                                 kFacevaryingScope );

    // Set a mesh sample.
    // We're creating the sample inline here,
    // but we could create a static sample and leave it around,
    // only modifying the parts that have changed.
    OPolyMeshSchema::Sample mesh_samp(
        V3fArraySample( ( const V3f * )g_verts, g_numVerts ),
        Int32ArraySample( g_indices, g_numIndices ),
        Int32ArraySample( g_counts, g_numCounts ),
        uvsamp, nsamp );

    // not actually the right data; just making it up
    Box3d cbox;
    cbox.extendBy( V3d( 1.0, -1.0, 0.0 ) );
    cbox.extendBy( V3d( -1.0, 1.0, 3.0 ) );
    mesh_samp.setChildBounds( cbox );

    // Set the sample twice
    mesh.set( mesh_samp );
    mesh.set( mesh_samp );


    // Alembic objects close themselves automatically when they go out
    // of scope. So - we don't have to do anything to finish
    // them off!
    std::cout << "Writing: " << archive.getName() << std::endl;
}
Ejemplo n.º 5
0
//-*****************************************************************************
void ISubDDrw::setTime( chrono_t iSeconds )
{
    IObjectDrw::setTime( iSeconds );
    if ( !valid() )
    {
        m_drwHelper.makeInvalid();
        return;
    }

    // Use nearest for now.
    ISampleSelector ss( iSeconds, ISampleSelector::kNearIndex );
    ISubDSchema::Sample psamp;

    if ( m_subD.getSchema().isConstant() )
    {
        psamp = m_samp;
    }
    else if ( m_subD.getSchema().getNumSamples() > 0 )
    {
        m_subD.getSchema().get( psamp, ss );
    }

    // Get the stuff.
    P3fArraySamplePtr P = psamp.getPositions();
    Int32ArraySamplePtr indices = psamp.getFaceIndices();
    Int32ArraySamplePtr counts = psamp.getFaceCounts();

    Box3d bounds;
    bounds.makeEmpty();

    if ( m_boundsProp && m_boundsProp.getNumSamples() > 0 )
    { bounds = m_boundsProp.getValue( ss ); }

    // Update the mesh hoo-ha.
    m_drwHelper.update( P, V3fArraySamplePtr(),
                        indices, counts, bounds );

    if ( !m_drwHelper.valid() )
    {
        m_subD.reset();
        return;
    }

    // The Object update computed child bounds.
    // Extend them by this.
    if ( !m_drwHelper.getBounds().isEmpty() )
    {
        m_bounds.extendBy( m_drwHelper.getBounds() );
    }
}
Ejemplo n.º 6
0
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	ConstSceneInterfacePtr s = scene( path );
	if( !s )
	{
		return Box3f();
	}
	
	Box3d b = s->readBound( context->getFrame() / g_frameRate );
	
	if( b.isEmpty() )
	{
		return Box3f();
	}
	
	return Box3f( b.min, b.max );
}
Ejemplo n.º 7
0
void BulletWorld::setBoundary(const Box3d<float>& box)
{
	btBoxShape* worldBoxShape = new btBoxShape( BulletConverter::convert( box.getLength() * 0.5 ));

	///create 6 planes/half spaces
	for (int i = 0; i < 6; i++)
	{
		btTransform groundTransform;
		groundTransform.setIdentity();
		groundTransform.setOrigin(BulletConverter::convert( box.getCenter()) );
		btVector4 planeEq;
		worldBoxShape->getPlaneEquation(planeEq, i);

		btCollisionShape* shape = new btStaticPlaneShape(-planeEq, planeEq[3]);
		btDefaultMotionState* state = new btDefaultMotionState(groundTransform);
		btRigidBody::btRigidBodyConstructionInfo plain_body_ci(0.0f, state, shape);
		btRigidBody* body = new btRigidBody(plain_body_ci);
		world->addRigidBody(body);
	}
	/*
	{
		btStaticPlaneShape* shape = new btBoxShape(BulletConverter::convert(box));
		btDefaultMotionState* state = new btDefaultMotionState();
		btRigidBody::btRigidBodyConstructionInfo plain_body_ci(0.0f, state, shape);
		btRigidBody* body = new btRigidBody(plain_body_ci);
		world->addRigidBody(body);
	}

	{
		btStaticPlaneShape* shape = new btStaticPlaneShape(btVector3(1.0f, 0.0f, 0.0f), box.getMinX());
		btDefaultMotionState* state = new btDefaultMotionState();
		btRigidBody::btRigidBodyConstructionInfo plain_body_ci(0.0f, state, shape);
		btRigidBody* body = new btRigidBody(plain_body_ci);
		world->addRigidBody(body);
	}

	{
		btCollisionShape* shape = new btStaticPlaneShape(btVector3(0.0f, 0.0f, 1.0f), box.getMinZ());
		btDefaultMotionState* state = new btDefaultMotionState();
		btRigidBody::btRigidBodyConstructionInfo plain_body_ci(0.0f, state, shape);
		btRigidBody* body = new btRigidBody(plain_body_ci);
		world->addRigidBody(body);
	}
	*/
}
Ejemplo n.º 8
0
  void VisualSceneSpecPoints :: BuildScene (int zoomall)
  {
    if (!mesh) 
      {
	VisualScene::BuildScene(zoomall);
	return;
      }
  
    Box3d box;
  
    if (mesh->GetNSeg())
      {
	box.SetPoint (mesh->Point (mesh->LineSegment(1)[0]));
	for (int i = 1; i <= mesh->GetNSeg(); i++)
	  {
	    box.AddPoint (mesh->Point (mesh->LineSegment(i)[0]));
	    box.AddPoint (mesh->Point (mesh->LineSegment(i)[1]));
	  }
      }
    else if (specpoints.Size() >= 2)
      {
	box.SetPoint (specpoints.Get(1).p);
	for (int i = 2; i <= specpoints.Size(); i++)
	  box.AddPoint (specpoints.Get(i).p);
      }
    else
      {
	box = Box3d (Point3d (0,0,0), Point3d (1,1,1));
      }
  
    if (zoomall == 2 && ((vispar.centerpoint >= 1 && vispar.centerpoint <= mesh->GetNP()) ||
			 vispar.use_center_coords))
      {
	if (vispar.use_center_coords)
	  {
	    center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; 
	  }
	else
	  center = mesh->Point (vispar.centerpoint);
      }
    else
      center = Center (box.PMin(), box.PMax());
        

    rad = 0.5 * Dist (box.PMin(), box.PMax());
  
  
    CalcTransformationMatrices();
  }
Ejemplo n.º 9
0
PhysicsObject::PhysicsObject(const Box3d<float>& box, const float divideLength, const SPHConstant& constant):
	constant(constant),
	nextId(0)
{
	const auto points = box.toPoints(divideLength);
	for (const auto& pos : points) {
		SPHParticle* p = new SPHParticle(pos, divideLength*0.5f, &this->constant, nextId++);
		particles.push_back(p);
	}
}
Ejemplo n.º 10
0
std::vector<SPHParticle*> PhysicsObject::createParticles(const Box3d<float>& box, const float divideLength)
{
	std::vector<SPHParticle*> newParticles;
	const auto points = box.toPoints(divideLength);
	for (const auto& pos : points) {
		SPHParticle* p = new SPHParticle(pos, divideLength*0.5f, &this->constant, nextId++);
		particles.push_back(p);
		newParticles.push_back(p);
	}
	return newParticles;
}
Ejemplo n.º 11
0
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	std::string fileName = fileNamePlug()->getValue();
	if( !fileName.size() )
	{
		return Box3f();
	}
	
	ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
	s = s->scene( path );
	
	Box3d b = s->readBound( context->getFrame() / g_frameRate );
	
	if( b.isEmpty() )
	{
		return Box3f();
	}
	
	return Box3f( b.min, b.max );
}
Ejemplo n.º 12
0
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	ConstSceneInterfacePtr s = scene( path );
	if( !s )
	{
		return Box3f();
	}

	if( s->hasBound() )
	{
		const Box3d b = s->readBound( context->getTime() );
		if( b.isEmpty() )
		{
			return Box3f();
		}
		return Box3f( b.min, b.max );
	}
	else
	{
		return unionOfTransformedChildBounds( path, parent );
	}
}
Ejemplo n.º 13
0
/*
Funzione chiamata dalla Align ad ogni ciclo
Riempie i vettori <MovVert> e <MovNorm> con i coordinate e normali presi dal vettore di vertici mov 
della mesh da muovere trasformata secondo la matrice <In>
Calcola anche il nuovo bounding box di tali vertici trasformati.
*/
bool AlignPair::InitMov(
		vector< Point3d > &MovVert,
		vector< Point3d > &MovNorm,
		Box3d &trgbox,
		const Matrix44d &in	)				// trasformazione Iniziale (che porta i punti di trg su src)
{
	Point3d pp,nn;

	MovVert.clear();
	MovNorm.clear();
	trgbox.SetNull();

	A2Mesh::VertexIterator vi;
	for(vi=mov->begin(); vi!=mov->end(); vi++) {
		pp=in*(*vi).P();
		nn=in*Point3d((*vi).P()+(*vi).N())-pp;
		nn.Normalize();
		MovVert.push_back(pp);
		MovNorm.push_back(nn);
		trgbox.Add(pp);
	}
	return true;
}
Ejemplo n.º 14
0
Intervald Sphere::proc(const Box<double>& x) 
{
  Box3d x1;
  Box3d center;
  Box3d diff;
  Intervald m_rtemp;

  if (x.size() == 3)
    {
      x1 = x;
      center = Box<double>(convert(m_x));
      m_rtemp = Intervald(m_r);
    }
  else
    {
      x1 = Box3d(x[0],x[1],x[2]);
      center =  m_xlrp(x[3]);
      m_rtemp = m_rlrp(x[3]);
    }

  diff = x1 - center;
  return diff.length() - m_rtemp;
} 
Ejemplo n.º 15
0
void worldToVoxel(const Field3D::FieldMapping* mapping,
                  const Box3d &wsBounds,
                  Box3d &vsBounds)
{
  V3d test1, test2;
  mapping->worldToVoxel(test1, test2);
  //! \todo Make this integrate over time
  V3d wsVerts[] = {
    V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.min.z),
    V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.min.z),
    V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.min.z),
    V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.min.z),
    V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.max.z),
    V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.max.z),
    V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.max.z),
    V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.max.z)
  };
  vsBounds.makeEmpty();
  V3d vsP;
  for (int i = 0; i < 8; i++) {
    mapping->worldToVoxel(wsVerts[i], vsP);
    vsBounds.extendBy(vsP);
  }
}
Ejemplo n.º 16
0
Box3d Sphere::grad(const Box<double>& x)
{
  Box3d x1;
  Box3d center;
  Box3d g;

  if (x.size() == 3)
    {
      x1 = x;
      center = Box<double>(convert(m_x));
    }
  else
    {
      x1 = Box3d(x[0],x[1],x[2]);
      center = m_xlrp(x[3]);
    }

  g = x1 - center;
  Intervald l = g.lengthSquared();
  if (l.isZero())
    return Box3d(0.0);
  else
    return g / l.sqrt();
}
Ejemplo n.º 17
0
void ParticleObject::add(const Box3d<float>& box, const float diameter, const float charge)
{
	for (auto x = box.getMinX(); x < box.getMaxX(); x += diameter) {
		for (auto y = box.getMinY(); y < box.getMaxY(); y += diameter) {
			for (auto z = box.getMinZ(); z < box.getMaxZ(); z += diameter) {
				const Vector3d<float> pos(x, y, z);
				particles.push_back(new Particle(pos, 1.0f, diameter * 0.5f));
			}
		}
	}
	sort();
}
void PaintCanvas::fitScreen() {
	Object* obj = activeObject();
	if (obj) {
		Box3d box;
		if (dynamic_cast<Map*>(obj))
			box = Geom::bounding_box(dynamic_cast<Map*>(obj));
		else if (dynamic_cast<PointSet*>(obj))
			box = Geom::bounding_box(dynamic_cast<PointSet*>(obj));

		qglviewer::Vec vmin(box.x_min(), box.y_min(), box.z_min());
		qglviewer::Vec vmax(box.x_max(), box.y_max(), box.z_max());

		//Vec vmin(-2.0f, -2.0f, -2.0f);
		//Vec vmax(2.0f, 2.0f, 2.0f);
		setSceneBoundingBox(vmin, vmax);
		showEntireScene();
	}
	updateGL();
}
//-*****************************************************************************
//-*****************************************************************************
// DO IT.
//-*****************************************************************************
//-*****************************************************************************
int main( int argc, char *argv[] )
{
    if ( argc != 2 )
    {
        std::cerr << "USAGE: " << argv[0] << " <AlembicArchive.abc>"
                  << std::endl;
        exit( -1 );
    }

    // Scoped.
    g_bounds.makeEmpty();
    {
        IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(),
                          argv[1], ErrorHandler::kQuietNoopPolicy );
        visitObject( archive.getTop() );
    }

    std::cout << "/" << " " << g_bounds.min << " " << g_bounds.max << std::endl;

    return 0;
}
//-*****************************************************************************
Box3d getBounds( IObject iObj )
{
    Box3d bnds;
    bnds.makeEmpty();

    M44d xf = getFinalMatrix( iObj );

    if ( IPolyMesh::matches( iObj.getMetaData() ) )
    {
        IPolyMesh mesh( iObj, kWrapExisting );
        IPolyMeshSchema ms = mesh.getSchema();
        V3fArraySamplePtr positions = ms.getValue().getPositions();
        size_t numPoints = positions->size();

        for ( size_t i = 0 ; i < numPoints ; ++i )
        {
            bnds.extendBy( (*positions)[i] );
        }
    }
    else if ( ISubD::matches( iObj.getMetaData() ) )
    {
        ISubD mesh( iObj, kWrapExisting );
        ISubDSchema ms = mesh.getSchema();
        V3fArraySamplePtr positions = ms.getValue().getPositions();
        size_t numPoints = positions->size();

        for ( size_t i = 0 ; i < numPoints ; ++i )
        {
            bnds.extendBy( (*positions)[i] );
        }
    }

    bnds.extendBy( Imath::transform( bnds, xf ) );

    g_bounds.extendBy( bnds );

    return bnds;
}
Ejemplo n.º 21
0
bool AlignPair::Align(
						A2Grid &u,
            A2GridVert &uv,
  		const	Matrix44d &in,					// trasformazione Iniziale (che porta i punti di mov su fix)
						Matrix44d &out,					// trasformazione calcolata
						vector<Point3d> &Pfix,		// vertici corrispondenti su src (rossi)
						vector<Point3d> &Nfix, 		// normali corrispondenti su src (rossi)
						vector<Point3d> &OPmov,		// vertici scelti su trg (verdi) prima della trasformazione in ingresso (Original Point Target)
						vector<Point3d> &ONmov, 		// normali scelti su trg (verdi)
						Histogramf &H,
						AlignPair::Stat &as)
{	
  vector<char> beyondCntVec;    // vettore per marcare i movvert che sicuramente non si devono usare
	                      // ogni volta che un vertice si trova a distanza oltre max dist viene incrementato il suo contatore;
												// i movvert che sono stati scartati piu' di MaxCntDist volte non si guardano piu';
  const int maxBeyondCnt=3;
	vector< Point3d > movvert;
	vector< Point3d > movnorm;
	vector<Point3d> Pmov; // vertici scelti dopo la trasf iniziale
	status=SUCCESS;
	int tt0=clock();  

	out=in;
	
	int i;

	double CosAngleThr=cos(ap.MaxAngleRad);
	double StartMinDist=ap.MinDistAbs;
	int tt1=clock();  
	int ttsearch=0;
	int ttleast=0;
	int nc=0;
	as.clear();
	as.StartTime=clock();
			
	beyondCntVec.resize(mov->size(),0);

  /**************** BEGIN ICP LOOP ****************/
    do
	{	
		Stat::IterInfo ii;
		Box3d movbox;
		InitMov(movvert,movnorm,movbox,out);
		H.SetRange(0,StartMinDist,512,2.5);
		Pfix.clear();
		Nfix.clear();
		Pmov.clear();
		OPmov.clear();
		ONmov.clear();
		int tts0=clock();
		ii.MinDistAbs=StartMinDist;
    int LocSampleNum=min(ap.SampleNum,int(movvert.size()));
    Box3d fixbox;
    if(u.Empty()) fixbox = uv.bbox;
    else fixbox = u.bbox;
    for(i=0;i<LocSampleNum;++i)
    {
      if( beyondCntVec[i] < maxBeyondCnt )
        if(! fixbox.IsIn(movvert[i]) )
          beyondCntVec[i]=maxBeyondCnt+1;
      else
      {
        double error=StartMinDist;
        Point3d closestPoint, closestNormal;
        double maxd= StartMinDist;
        ii.SampleTested++;
        if(u.Empty()) // using the point cloud grid
        {
          A2Mesh::VertexPointer vp = tri::GetClosestVertex(*fix,uv,movvert[i], maxd, error);
          if(error>=StartMinDist) {
            ii.DistanceDiscarded++; ++beyondCntVec[i]; continue;
          }
          if(movnorm[i].dot(vp->N()) < CosAngleThr) {
              ii.AngleDiscarded++; continue;
          }
          closestPoint=vp->P();
          closestNormal=vp->N();
        }
        else // using the standard faces and grid
        {
          A2Mesh::FacePointer f=vcg::tri::GetClosestFaceBase<vcg::AlignPair::A2Mesh, vcg::AlignPair::A2Grid >(*fix, u, movvert[i], maxd, error, closestPoint);
          if(error>=StartMinDist) {
            ii.DistanceDiscarded++; ++beyondCntVec[i]; continue;
          }
          if(movnorm[i].dot(f->N()) < CosAngleThr) {
              ii.AngleDiscarded++; continue;
          }
          Point3d ip;
          InterpolationParameters<A2Face,double>(*f,f->N(),closestPoint, ip);
          const double IP_EPS = 0.00001;
          // If ip[i] == 0 it means that we are on the edge opposite to i
          if(	(fabs(ip[0])<=IP_EPS && f->IsB(1)) ||  (fabs(ip[1])<=IP_EPS && f->IsB(2)) || (fabs(ip[2])<=IP_EPS && f->IsB(0))   ){
            ii.BorderDiscarded++;  continue;
          }
          closestNormal = f->N();
        }
        // The sample was accepted. Store it.
        Pmov.push_back(movvert[i]);
        OPmov.push_back((*mov)[i].P());
        ONmov.push_back((*mov)[i].N());
        Nfix.push_back( closestNormal );
        Pfix.push_back( closestPoint );
        H.Add(float(error));
        ii.SampleUsed++;
      }
    } // End for each pmov
    int tts1=clock();
		//printf("Found %d pairs\n",(int)Pfix.size());
    if(!ChoosePoints(Pfix,Nfix,Pmov,OPmov,ap.PassHiFilter,H))
    if(int(Pfix.size())<ap.MinPointNum)
		{
			status = TOO_FEW_POINTS;
			ii.Time=clock();
			as.I.push_back(ii);
			return false;
		}
		Matrix44d newout;
		switch(ap.MatchMode) {
		case AlignPair::Param::MMSimilarity : ComputeRotoTranslationScalingMatchMatrix(newout,Pfix,OPmov); break;
		case AlignPair::Param::MMRigid   : ComputeRigidMatchMatrix(Pfix,OPmov,newout);   break;
			default :
						status = UNKNOWN_MODE;
						ii.Time=clock();
						as.I.push_back(ii);
						return false;
		}
					
//    double sum_before=0;
//    double sum_after=0;
//    for(unsigned int iii=0;iii<Pfix.size();++iii)
//    {
//      sum_before+=Distance(Pfix[iii], out*OPmov[iii]);
//      sum_after+=Distance(Pfix[iii], newout*OPmov[iii]);
//    }
//    //printf("Distance %f -> %f\n",sum_before/double(Pfix.size()),sum_after/double(Pfix.size()) ) ;
   
		// le passate successive utilizzano quindi come trasformazione iniziale questa appena trovata.
		// Nei prossimi cicli si parte da questa matrice come iniziale.
	  out=newout;

		assert(Pfix.size()==Pmov.size());
		int tts2=clock();
		ttsearch+=tts1-tts0;	
		ttleast +=tts2-tts1;
    ii.pcl50=H.Percentile(.5);
		ii.pclhi=H.Percentile(ap.PassHiFilter);
		ii.AVG=H.Avg();
		ii.RMS=H.RMS();
		ii.StdDev=H.StandardDeviation();
		ii.Time=clock();
		as.I.push_back(ii);
		nc++;
		// The distance of the next points to be considered is lowered according to the <ReduceFactor> parameter. 
		// We use 5 times the <ReduceFactor> percentile of the found points. 
    if(ap.ReduceFactorPerc<1) StartMinDist=max(ap.MinDistAbs*ap.MinMinDistPerc, min(StartMinDist,5.0*H.Percentile(ap.ReduceFactorPerc)));
	} 
	while ( 
		nc<=ap.MaxIterNum && 
		H.Percentile(.5) > ap.TrgDistAbs && 
		(nc<ap.EndStepNum+1 || ! as.Stable(ap.EndStepNum) ) 
		); 
 /**************** END ICP LOOP ****************/
	int tt2=clock();  
	Matrix44d ResCopy=out;
	Point3d scv,shv,rtv,trv;
	Decompose(ResCopy,scv,shv,rtv,trv);
  if(math::Abs(1-scv[0])>ap.MaxScale || math::Abs(1-scv[1])>ap.MaxScale || math::Abs(1-scv[2])>ap.MaxScale ) {
			status = TOO_MUCH_SCALE;
			return false;
		}
	if(shv[0]>ap.MaxShear || shv[1]>ap.MaxShear || shv[2]>ap.MaxShear ) {
			status = TOO_MUCH_SHEAR;
			return false;
		}
	printf("Grid %i %i %i - fn %i\n",u.siz[0],u.siz[1],u.siz[2],fix->fn);
  printf("Init %8.3f Loop %8.3f Search %8.3f least sqrt %8.3f\n",
         float(tt1-tt0)/CLOCKS_PER_SEC, float(tt2-tt1)/CLOCKS_PER_SEC,
         float(ttsearch)/CLOCKS_PER_SEC,float(ttleast)/CLOCKS_PER_SEC );

	return true;
}
Ejemplo n.º 22
0
void FixedRenderer::drawScene(Scene * scene, OCamera * camera)
{
	struct MEntityLight
	{
		Box3d lightBox;
		OLight * light;
	};

	struct MSubMeshPass
	{
		unsigned int subMeshId;
		unsigned int lightsNumber;
		Object3d * object;
		OLight * lights[4];
	};

	// sub objects
	#define MAX_TRANSP_SUBOBJ 4096
	static int transpList[MAX_TRANSP_SUBOBJ];
	static float transpZList[MAX_TRANSP_SUBOBJ];
	static MSubMeshPass transpSubObjs[MAX_TRANSP_SUBOBJ];

	// lights list
	#define MAX_ENTITY_LIGHTS 256
	static int entityLightsList[MAX_ENTITY_LIGHTS];
	static float entityLightsZList[MAX_ENTITY_LIGHTS];
	static MEntityLight entityLights[MAX_ENTITY_LIGHTS];


	// get render
	RenderingContext * render = NeoEngine::getInstance()->getRenderingContext();
	render->enableLighting();
	render->enableBlending();


	// make frustum
	Frustum * frustum = camera->getFrustum();
	frustum->makeVolume(camera);

	// update visibility
	updateVisibility(scene, camera);

	// fog
	enableFog(camera);

	// camera
	Vector3 cameraPos = camera->getTransformedPosition();


	// transp sub obj number
	unsigned int transpSubObsNumber = 0;

	// lights
	unsigned int l;
	unsigned int lSize = scene->getLightsNumber();

	// entities
	unsigned int i;
	unsigned int eSize = scene->getEntitiesNumber();
	for(i=0; i<eSize; i++)
	{
		// get entity
		OEntity * entity = scene->getEntityByIndex(i);
		Mesh * mesh = entity->getMesh();

		if(! entity->isActive())
			continue;

		if(! entity->isVisible())
		{
			if(mesh)
			{
				Armature * armature = mesh->getArmature();
				ArmatureAnim * armatureAnim = mesh->getArmatureAnim();
				if(armature)
				{
					// animate armature
					if(mesh->getArmature())
					{
						Armature * armature = mesh->getArmature();
						if(mesh->getArmatureAnim())
						{
							animateArmature(
								mesh->getArmature(),
								mesh->getArmatureAnim(),
								entity->getCurrentFrame()
							);
						}
						else
						{
							armature->processBonesLinking();
							armature->updateBonesSkinMatrix();
						}
					}

					// TODO : optimize and add a tag to desactivate it
					updateSkinning(mesh, armature);
					(*entity->getBoundingBox()) = (*mesh->getBoundingBox());
				}
			}

			continue;
		}

		// draw mesh
		if(mesh)
		{
			Vector3 scale = entity->getTransformedScale();
			Box3d * entityBox = entity->getBoundingBox();

			float minScale = scale.x;
			minScale = MIN(minScale, scale.y);
			minScale = MIN(minScale, scale.z);
			minScale = 1.0f / minScale;

			unsigned int entityLightsNumber = 0;
			for(l=0; l<lSize; l++)
			{
				// get entity
				OLight * light = scene->getLightByIndex(l);

				if(! light->isActive())
					continue;

				if(! light->isVisible())
					continue;

				// light box
				Vector3 lightPos = light->getTransformedPosition();
				Vector3 localPos = entity->getInversePosition(lightPos);

				float localRadius = light->getRadius() * minScale;

				Box3d lightBox(
								Vector3(localPos - localRadius),
								Vector3(localPos + localRadius)
								);

				if(! entityBox->isInCollisionWith(lightBox))
					continue;

				MEntityLight * entityLight = &entityLights[entityLightsNumber];
				entityLight->lightBox = lightBox;
				entityLight->light = light;

				entityLightsNumber++;
				if(entityLightsNumber == MAX_ENTITY_LIGHTS)
					break;
			}

			// animate armature
			if(mesh->getArmature())
			{
				Armature * armature = mesh->getArmature();
				if(mesh->getArmatureAnim())
				{
					animateArmature(
						mesh->getArmature(),
						mesh->getArmatureAnim(),
						entity->getCurrentFrame()
					);
				}
				else
				{
					armature->processBonesLinking();
					armature->updateBonesSkinMatrix();
				}
			}

			// animate textures
			if(mesh->getTexturesAnim())
				animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame());

			// animate materials
			if(mesh->getMaterialsAnim())
				animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame());

			unsigned int s;
			unsigned int sSize = mesh->getSubMeshsNumber();
			for(s=0; s<sSize; s++)
			{
				SubMesh * subMesh = &mesh->getSubMeshs()[s];
				Box3d * box = subMesh->getBoundingBox();

				// check if submesh visible
				if(sSize > 1)
				{
					Vector3 * min = &box->min;
					Vector3 * max = &box->max;

					Vector3 points[8] = {
						entity->getTransformedVector(Vector3(min->x, min->y, min->z)),
						entity->getTransformedVector(Vector3(min->x, max->y, min->z)),
						entity->getTransformedVector(Vector3(max->x, max->y, min->z)),
						entity->getTransformedVector(Vector3(max->x, min->y, min->z)),
						entity->getTransformedVector(Vector3(min->x, min->y, max->z)),
						entity->getTransformedVector(Vector3(min->x, max->y, max->z)),
						entity->getTransformedVector(Vector3(max->x, max->y, max->z)),
						entity->getTransformedVector(Vector3(max->x, min->y, max->z))
					};

					if(! frustum->isVolumePointsVisible(points, 8))
						continue;
				}

				// subMesh center
				Vector3 center = box->min + (box->max - box->min)*0.5f;
				center = entity->getTransformedVector(center);

				// sort entity lights
				unsigned int lightsNumber = 0;
				for(l=0; l<entityLightsNumber; l++)
				{
					MEntityLight * entityLight = &entityLights[l];
					if(! box->isInCollisionWith(entityLight->lightBox))
						continue;

					OLight * light = entityLight->light;

					float z = (center - light->getTransformedPosition()).getLength();
					entityLightsList[lightsNumber] = l;
					entityLightsZList[l] = (1.0f/z)*light->getRadius();
					lightsNumber++;
				}

				if(lightsNumber > 1)
					sortFloatList(entityLightsList, entityLightsZList, 0, (int)lightsNumber-1);

				// local lights
				if(lightsNumber > 4)
					lightsNumber = 4;

				for(l=0; l<lightsNumber; l++)
				{
					MEntityLight * entityLight = &entityLights[entityLightsList[l]];
					OLight * light = entityLight->light;

					// attenuation
					float quadraticAttenuation = (8.0f / light->getRadius());
					quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity();

					// color
					Vector3 color = light->getFinalColor();

					// set light
					render->enableLight(l);
					render->setLightPosition(l, light->getTransformedPosition());
					render->setLightDiffuse(l, Vector4(color));
					render->setLightSpecular(l, Vector4(color));
					render->setLightAmbient(l, Vector3(0, 0, 0));
					render->setLightAttenuation(l, 1, 0, quadraticAttenuation);

					// spot
					render->setLightSpotAngle(l, light->getSpotAngle());
					if(light->getSpotAngle() < 90){
						render->setLightSpotDirection(l, light->getRotatedVector(Vector3(0, 0, -1)).getNormalized());
						render->setLightSpotExponent(l, light->getSpotExponent());
					}
					else {
						render->setLightSpotExponent(l, 0.0f);
					}
				}

				for(l=lightsNumber; l<4; l++){
					render->disableLight(l);
				}

				render->pushMatrix();
				render->multMatrix(entity->getMatrix());

				// draw opaques
				drawOpaques(subMesh, mesh->getArmature());

				if(subMesh->hasTransparency())
				{
					if(transpSubObsNumber < MAX_TRANSP_SUBOBJ)
					{
						// transparent subMesh pass
						MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber];

						// lights
						subMeshPass->lightsNumber = lightsNumber;
						for(l=0; l<lightsNumber; l++)
							subMeshPass->lights[l] = entityLights[entityLightsList[l]].light;

						// z distance to camera
						float z = getDistanceToCam(camera, center);

						// set values
						transpList[transpSubObsNumber] = transpSubObsNumber;
						transpZList[transpSubObsNumber] = z;
						subMeshPass->subMeshId = s;
						subMeshPass->object = entity;

						transpSubObsNumber++;
					}
				}

				render->popMatrix();
			}

			mesh->updateBoundingBox();
			(*entity->getBoundingBox()) = (*mesh->getBoundingBox());
		}
	}


	// texts
	unsigned int tSize = scene->getTextsNumber();
	for(i=0; i<tSize; i++)
	{
		OText * text = scene->getTextByIndex(i);
		if(text->isActive() && text->isVisible())
		{
			// transparent pass
			MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber];

			// center
			Box3d * box = text->getBoundingBox();
			Vector3 center = box->min + (box->max - box->min)*0.5f;
			center = text->getTransformedVector(center);

			// z distance to camera
			float z = getDistanceToCam(camera, center);

			// set values
			transpList[transpSubObsNumber] = transpSubObsNumber;
			transpZList[transpSubObsNumber] = z;
			subMeshPass->object = text;

			transpSubObsNumber++;
		}
	}


	// sort transparent list
	if(transpSubObsNumber > 1)
		sortFloatList(transpList, transpZList, 0, (int)transpSubObsNumber-1);

	// draw transparents
	render->setDepthMask(0);
	
	for(i=0; i<transpSubObsNumber; i++)
	{
		MSubMeshPass * subMeshPass = &transpSubObjs[transpList[i]];
		Object3d * object = subMeshPass->object;

		// objects
		switch(object->getType())
		{
			case M_OBJECT3D_ENTITY:
			{
				OEntity * entity = (OEntity *)object;
				unsigned int subMeshId = subMeshPass->subMeshId;
				Mesh * mesh = entity->getMesh();
				SubMesh * subMesh = &mesh->getSubMeshs()[subMeshId];

				// animate armature
				if(mesh->getArmature())
				{
					Armature * armature = mesh->getArmature();
					if(mesh->getArmatureAnim())
					{
						animateArmature(
							mesh->getArmature(),
							mesh->getArmatureAnim(),
							entity->getCurrentFrame()
						);
					}
					else
					{
						armature->processBonesLinking();
						armature->updateBonesSkinMatrix();
					}
				}

				// animate textures
				if(mesh->getTexturesAnim())
					animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame());

				// animate materials
				if(mesh->getMaterialsAnim())
					animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame());

				// lights
				for(l=0; l<subMeshPass->lightsNumber; l++)
				{
					OLight * light = subMeshPass->lights[l];

					// attenuation
					float quadraticAttenuation = (8.0f / light->getRadius());
					quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity();

					// color
					Vector3 color = light->getFinalColor();

					// set light
					render->enableLight(l);
					render->setLightPosition(l, light->getTransformedPosition());
					render->setLightDiffuse(l, Vector4(color));
					render->setLightSpecular(l, Vector4(color));
					render->setLightAmbient(l, Vector3(0, 0, 0));
					render->setLightAttenuation(l, 1, 0, quadraticAttenuation);

					// spot
					render->setLightSpotAngle(l, light->getSpotAngle());
					if(light->getSpotAngle() < 90){
						render->setLightSpotDirection(l, light->getRotatedVector(Vector3(0, 0, -1)).getNormalized());
						render->setLightSpotExponent(l, light->getSpotExponent());
					}
					else {
						render->setLightSpotExponent(l, 0.0f);
					}
				}

				for(l=subMeshPass->lightsNumber; l<4; l++){
					render->disableLight(l);
				}

				render->pushMatrix();
				render->multMatrix(entity->getMatrix());
				drawTransparents(subMesh, mesh->getArmature());
				render->popMatrix();

				mesh->updateBoundingBox();
				(*entity->getBoundingBox()) = (*mesh->getBoundingBox());
			}
				break;

			case M_OBJECT3D_TEXT:
			{
				OText * text = (OText *)object;

				render->pushMatrix();
				render->multMatrix(text->getMatrix());
				drawText(text);
				render->popMatrix();
			}
				break;
		}
	}
	
	render->setDepthMask(1);

	render->disableLighting();
	render->disableFog();
}