示例#1
0
FixedRect GeodataMock::calculateBoundingBox(const Relation* relation) const {


	coord_t maxX = std::numeric_limits<coord_t>::min();
	coord_t maxY = std::numeric_limits<coord_t>::min();
	coord_t minX = std::numeric_limits<coord_t>::max();
	coord_t minY = std::numeric_limits<coord_t>::max();

	const std::vector<NodeId>& nodeIDs = relation->getNodeIDs();
	if (nodeIDs.size() > 0)
	{
		FixedRect result = calculateBoundingBox(nodeIDs);
		minX = result.minX;
		minY = result.minY;
		maxX = result.maxX;
		maxY = result.maxY;
	}

	const std::vector<WayId>& wayIDs = relation->getWayIDs();
	for (WayId i : wayIDs) {
		FixedRect bounds = calculateBoundingBox(getWay(i));
		minX = std::min(minX, bounds.minX);
		minY = std::min(minY, bounds.minY);
		maxX = std::max(maxX, bounds.maxX);
		maxY = std::max(maxY, bounds.maxY);
	}

	if (maxX < minX || maxY < minY)
		return FixedRect(0, 0, 0, 0);

	return FixedRect(minX, minY, maxX, maxY);
}
示例#2
0
	void
	FlowDesigner::updateConnectionCoords(QMouseEvent *event) {
		if (m_connectingPort == NULL) return;

		float x = event->x();
		float y = event->y();

		// Find the starting x and y's
		QRectF compBounds = calculateBoundingBox(*m_connectingPort->getComponent());
		QRectF bounds = calculatePortBoundingBox(*m_connectingPort, compBounds);
		m_connectingSX = bounds.x() + 0.5f * bounds.width();
		m_connectingSY = bounds.y() + 0.5f * bounds.height();

		float ex = x;
		float ey = y;

		// Do a snap-to for the final x and y's
		Component *comp = getComponentIntersection(x, y);
		
		if (comp != NULL) {
			Port *port = getPortIntersection(comp, x, y);
			if (port) {
				QRectF compBounds = calculateBoundingBox(*comp);
				QRectF bounds = calculatePortBoundingBox(*port, compBounds);
				
				ex = bounds.x() + 0.5f * bounds.width();
				ey = bounds.y() + 0.5f * bounds.height();
			}
		}

		m_connectingEX = ex;
		m_connectingEY = ey;

		repaint();
	}
示例#3
0
struct OBJ_Model * loadObj(char * directory,char * filename /*This does not have a .obj extension*/,int compileDisplayList)
{
    fprintf(stderr,"Starting to load  OBJ file %s \n",filename);
    struct OBJ_Model * obj = ( struct OBJ_Model * ) malloc(sizeof(struct OBJ_Model));
    if ( obj == 0 )  { fprintf(stderr,"Could not allocate enough space for model %s \n",filename);  return 0; }


    memset (obj,0,sizeof(struct OBJ_Model));
	obj->scale=1.0f;


    unsigned int directory_length = strlen(directory);
    if (directory_length > MAX_MODEL_PATHS ) { fprintf(stderr,"Huge directory filename provided , will not loadObject ( %u char limit ) \n",MAX_MODEL_PATHS); free(obj); return 0; }
	strncpy(obj->directory, directory, MAX_MODEL_PATHS );

    unsigned int file_name_length = strlen(filename);
    if (file_name_length > MAX_MODEL_PATHS ) { fprintf(stderr,"Huge filename provided , will not loadObject ( %u char limit ) \n",MAX_MODEL_PATHS); free(obj); return 0; }
	strncpy(obj->filename, filename, MAX_MODEL_PATHS );

    if (!readOBJ(obj) ) { fprintf(stderr," Could not read object %s \n",filename); unloadObj(obj); return 0;}
    if (!calculateBoundingBox(obj)) { fprintf(stderr," Could not calculate bounding box for object %s \n",filename); unloadObj(obj); return 0;}
    if (!prepareObject(obj))  { fprintf(stderr," Could not prepare object %s \n",filename); unloadObj(obj); return 0;}
    if (!calculateBoundingBox(obj)) { fprintf(stderr," Could not calculate bounding box for object %s \n",filename); unloadObj(obj); return 0;}

   if (compileDisplayList)
   {
     compileOBJList(obj);
   }


   return obj;
}
示例#4
0
文件: QuadNode.cpp 项目: cpzhang/zen
void QuadNode::calculateBoundingBox( QuadNode* n )
{
	if (NULL == n)
	{
		return;
	}
	n->boundingBox_.max_ = Vector3(n->rect_.right_, 0.0f, n->rect_.top_);
	n->boundingBox_.min_ = Vector3(n->rect_.left_, 0.0f, n->rect_.bottom_);
// 	if (n->insideChunk_)
// 	{
// 		for (int x = n->xNumber_; x !)
// 		{
// 		}
// 	}
// 	else
	{
		if (n->leaf_)
		{
			Chunk* ck = getSceneManager()->getTerrain()->getChunkFromTopology(n->xNumber_, n->zNumber_);
			n->boundingBox_.max_.y = ck->getMaxHeight();
			n->boundingBox_.min_.y = ck->getMinHeight();
		}
	}
	
	QuadNode* m = NULL;
	m = n->children_[eQuadNode_LeftBottom];
	if (m)
	{
		calculateBoundingBox(m);
		n->boundingBox_.max_.y = max(n->boundingBox_.max_.y, m->boundingBox_.max_.y);
		n->boundingBox_.min_.y = min(n->boundingBox_.min_.y, m->boundingBox_.min_.y);
	}
	m = n->children_[eQuadNode_RightBottom];
	if (m)
	{
		calculateBoundingBox(m);
		n->boundingBox_.max_.y = max(n->boundingBox_.max_.y, m->boundingBox_.max_.y);
		n->boundingBox_.min_.y = min(n->boundingBox_.min_.y, m->boundingBox_.min_.y);
	}
	m = n->children_[eQuadNode_LeftTop];
	if (m)
	{
		calculateBoundingBox(m);
		n->boundingBox_.max_.y = max(n->boundingBox_.max_.y, m->boundingBox_.max_.y);
		n->boundingBox_.min_.y = min(n->boundingBox_.min_.y, m->boundingBox_.min_.y);
	}
	m = n->children_[eQuadNode_RightTop];
	if (m)
	{
		calculateBoundingBox(m);
		n->boundingBox_.max_.y = max(n->boundingBox_.max_.y, m->boundingBox_.max_.y);
		n->boundingBox_.min_.y = min(n->boundingBox_.min_.y, m->boundingBox_.min_.y);
	}
}
bool Timeseries_2ndDerivative::updateCache()
{
    size_t data_size = _source_data->size();

    if( data_size <= 2)
    {
        _cached_data.clear();
        _bounding_box = QRectF();
        return true;
    }

    data_size = data_size - 2;
    _cached_data.resize( data_size );

    for (size_t i=0; i < data_size; i++ )
    {
        const auto& p0 = _source_data->at( i );
        const auto& p1 = _source_data->at( i+1 );
        const auto& p2 = _source_data->at( i+2 );
        const auto delta = (p2.x - p0.x) *0.5;
        const auto acc = ( p2.y - 2.0* p1.y + p0.y)/(delta*delta);
        QPointF p( (p2.x + p0.x)*0.5, acc );
        _cached_data[i] = { p.x(), p.y() };
    }

    calculateBoundingBox();
    return true;
}
bool Timeseries_1stDerivative::updateCache()
{
    size_t data_size = _source_data->size();

    if( data_size <= 1)
    {
        _cached_data.clear();
        _bounding_box = QRectF();
        return true;
    }

    data_size = data_size - 1;
    _cached_data.resize( data_size );

    for (size_t i=0; i < data_size; i++ )
    {
        const auto& p0 = _source_data->at( i );
        const auto& p1 = _source_data->at( i+1 );
        const auto delta = p1.x - p0.x;
        const auto vel = (p1.y - p0.y) /delta;
        QPointF p( (p1.x + p0.x)*0.5, vel);
        _cached_data[i] = { p.x(), p.y() };
    }

    calculateBoundingBox();
    return true;
}
示例#7
0
	Room::Room(const Room& rhs)
	{
		this->filename = rhs.filename;
		//int filenameLength = strlen(rhs.filename);
		//this->filename = new char[filenameLength];
		//this->filename = "";
		//stringCopy(this->filename, rhs.filename);
		this->world = rhs.world;
		tilemap = 0;
		doorsGrid = 0;
		collisionGrid = 0;
		rowStart = 0;
		rowEnd = 0;
		colStart = 0;
		colEnd = 0;
		roomWidth = 0;
		roomHeight = 0;
		box = 0;
		distance=0.0f;

		doors.clear();

		loadMap();
		calculateBoundingBox();
		locateDoors();

		for(unsigned int i=0; i < doors.size(); i++)
		{
			Door* door = doors[i];
			door->opened=true;
		}

		this->graphic = tilemap;
	}
示例#8
0
	Room::Room(char* filename, GameWorld* gameWorld) :
		Entity()
	{
		this->filename = filename;
		this->world = gameWorld;
		tilemap = 0;
		doorsGrid = 0;
		collisionGrid = 0;
		rowStart = 0;
		rowEnd = 0;
		colStart = 0;
		colEnd = 0;
		roomWidth = 0;
		roomHeight = 0;
		box = 0;
		distance=0.0f;

		doors.clear();

		loadMap();
		calculateBoundingBox();
		locateDoors();

		this->graphic = tilemap;
	}
示例#9
0
// called after the shape data changed
// used to sync extra short-hand data with the basic shape modified data
// ex: sync relative points with absolute points
// used to sync relative points with absolute points
void basicShape::onShapeModified(){
	// todo: position stuff
	
	// update boundingbox
	calculateBoundingBox();
	
}
VoroNode::VoroNode(ofVboMesh _mesh, VoroNode& vnParent) {
    counter++;
    isSplit = false;
    bDraw = true;
    
    level = vnParent.level+1;
    
    // make the mesh vertices local for the node
    // move th relative position to the nodes position
    // transformations on the unit are around the centroid of the mesh not the centroid of the parent
    mesh = _mesh;
    setPosition(mesh.getCentroid());
    
    for(int i=0; i<_mesh.getNumVertices(); i++) {
        mesh.setVertex(i,  _mesh.getVertex(i)-_mesh.getCentroid());
    }
    
    mesh.setupIndicesAuto();
    mesh.getVbo();
    
    calculateBoundingBox();
    
    setParent(vnParent);
    
};
示例#11
0
QgsRectangle QgsAbstractGeometryV2::boundingBox() const
{
    if ( mBoundingBox.isNull() )
    {
        mBoundingBox = calculateBoundingBox();
    }
    return mBoundingBox;
}
示例#12
0
QgsRectangle QgsCurve::boundingBox() const
{
  if ( mBoundingBox.isNull() )
  {
    mBoundingBox = calculateBoundingBox();
  }
  return mBoundingBox;
}
QgsRectangle QgsGeometryCollection::boundingBox() const
{
  if ( mBoundingBox.isNull() )
  {
    mBoundingBox = calculateBoundingBox();
  }
  return mBoundingBox;
}
示例#14
0
void
Shape::makeClean() const
{
    if (dirty_)
    {
        Dirtable::makeClean();
        calculateBoundingBox(bb_);
    }
}
示例#15
0
	Component *
	FlowDesigner::getComponentIntersection(float x, float y) {
		for (Component *comp : m_project->getComponents()) {
			QRectF bounding = calculateBoundingBox(*comp);

			if (bounding.contains(x, y)) return comp;
		}
		return NULL;
	}
VoroNode::VoroNode(ofVboMesh _mesh) {
    counter++;
    isSplit = false;
    mesh = _mesh;
    level = 0;
    clearParent();
    calculateBoundingBox();
    mesh.getVbo();
};
示例#17
0
	Port *
	FlowDesigner::getPortIntersection(Component *comp, float x, float y) {
		QRectF bounds = calculateBoundingBox(*comp);
		
		for (Port *p : comp->getPorts()) {
			QRectF box = calculatePortBoundingBox(*p, bounds);
			if (box.contains(x, y)) return p;
		}
		return NULL;
	}
示例#18
0
 shared_ptr<std::vector<WayId> > GeodataMock::getWayIDs(const FixedRect& rect) const
 {
 	shared_ptr<std::vector<WayId> > wayIDs = boost::make_shared< std::vector<WayId> >();
 	for(int i = 0; i < ways->size(); i++) {
 		if(rect.intersects(calculateBoundingBox(&ways->at(i)))) {
 				wayIDs->push_back(WayId(i));
 		}
 	}
 	return wayIDs;
 }
bool PointCloud::doBoundingBoxesOverlap( const BoundingBox &box) const {
	BoundingBox myBox = calculateBoundingBox();
	bool noOverlap = myBox.topLeft.getX()
			> box.topLeft.getX() + box.width
			|| box.topLeft.getX() > myBox.topLeft.getX() + myBox.width
			|| myBox.topLeft.getY()
					> box.topLeft.getY() + box.height
			|| box.topLeft.getY() > myBox.topLeft.getY() + myBox.width;

	return !noOverlap;
}
示例#20
0
 shared_ptr<std::vector<RelId> > GeodataMock::getRelationIDs(const FixedRect& rect) const
 {
	shared_ptr<std::vector<RelId> > relationIDs = boost::make_shared< std::vector<RelId> >();

 	for(int i = 0; i < relations->size(); i++) {
 		if ( rect.intersects ( calculateBoundingBox(&relations->at(i)))) {
			relationIDs->push_back(RelId(i));
 		}
 	}
 	return relationIDs;
 }
示例#21
0
    dp::math::Box3f ManagerBitSet::getBoundingBox( const GroupSharedPtr& group ) const
    {
      dp::util::ProfileEntry p("cull::getBoundingBox");

      GroupBitSetSharedPtr groupImpl = std::static_pointer_cast<GroupBitSet>(group);
      if ( groupImpl->isBoundingBoxDirty() )
      {
        groupImpl->setBoundingBox( calculateBoundingBox( group ) );
        groupImpl->setBoundingBoxDirty( false );
      }
      return groupImpl->getBoundingBox();
    }
示例#22
0
	void
	FlowDesigner::paintComponent(QPainter *painter, const Component &comp) {
		QRectF bounds = calculateBoundingBox(comp);

		//
		// Now, do the painting: 
		//

		paintComponentBox(painter, bounds, comp);
		paintComponentContent(painter, bounds, comp);
		paintComponentLinks(painter, bounds, comp);
	}
示例#23
0
// called after the shape was (hard) edited
// used to sync extra short-hand data with the basic shape original data
// ex: sync relative points with absolute points
void basicShape::onShapeEdited(){
	
	// update boundingbox
	calculateBoundingBox();
	
#ifdef KM_EDITOR_APP
	// update GUI Toggle ?
	if( isInEditMode() ){
		guiToggle.setPosition( boundingBox.getBottomLeft()+ofPoint(-5,5) );
	}
#endif
}
示例#24
0
	SoSeparator* IVWorkSpace::getIvFromPQPScene(bool bounding) {
		SoSeparator* pqp= new SoSeparator;
		for(unsigned int i=0;i<robots.size(); i++){
			pqp->addChild((SoSeparator*)robots[i]->getModelFromColl());
		}
		for(unsigned int i=0;i<obstacles.size(); i++){
			pqp->addChild((SoSeparator*)obstacles[i]->getModelFromColl());
		}
    if(bounding)
      pqp->addChild(calculateBoundingBox(pqp));
		return pqp;
	}
示例#25
0
																																					//
// Updates the mesh by calling the optimizeInPlace method
// of the D3DX object and reloading attribute information
void DirectX::Mesh::update( )
{
	DWORD* adjacencyInfo = new DWORD[m_mesh->GetNumFaces( )*sizeof(DWORD)];
	m_mesh->ConvertPointRepsToAdjacency( NULL, adjacencyInfo );
	m_mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT, adjacencyInfo, NULL, NULL, NULL );
	delete[] adjacencyInfo;

	if( m_attributeTable ) delete[] m_attributeTable;
	m_mesh->GetAttributeTable( NULL, &m_nAttributes );
	m_attributeTable = new D3DXATTRIBUTERANGE[m_nAttributes];
	m_mesh->GetAttributeTable( m_attributeTable, &m_nAttributes );

	calculateBoundingSphere( );
	calculateBoundingBox( );
}
示例#26
0
	SoSeparator* IVWorkSpace::getIvScene(bool bounding){
		if(scene == NULL){
      if(robots.size() != 0){
			  scene = new SoSeparator();
        //scene->addChild(SoUnits::MILLIMETERS);
			  for(unsigned int i=0; i<robots.size(); i++)
				  scene->addChild((SoSeparator*)robots[i]->getModel());
  			  			
        for(unsigned int i=0; i<obstacles.size(); i++){
				  SoSeparator* sep = (SoSeparator*)obstacles[i]->getModel();
				  char str[20];
				  sprintf(str,"obstacle%d",i);
				  sep->setName(str);
				  scene->addChild(sep);
				  //scene->addChild((SoSeparator*)obstacles[i]->getModel());
			  }
  			
			  for(unsigned int i=0; i<_mobileObstacle.size(); i++)
				  scene->addChild((SoSeparator*)_mobileObstacle[i]->getModel());

			  scene->ref();
      }
    }

		/* The following does not work properly when cildren should be accesseb by labels.
		   The scene pointer should be returned instead.*/
		/*
			SoSeparator* temp = new SoSeparator();
			temp->addChild(scene);
			temp->ref();
			if(bounding)
				temp->addChild(calculateBoundingBox(scene));
			return temp;
		*/

		//comporvacio
		//SoNode *sepgrid = scene->getByName("obstacle1");
		//int c = scene->findChild(sepgrid);
		//scene->removeChild(sepgrid);


		if(bounding)
			scene->addChild(calculateBoundingBox(scene));
		return scene;
	}
示例#27
0
MeshOctTree::MeshOctTree(ObjMesh *mesh)
{

    QTime t;
    t.start();

    m_mesh = mesh;

    maxDepth = 4;
    minTrianglesForSplitting = 5;

    calculateBoundingBox();

    m_root = new OctTreeNode(boundingMin, boundingMax, maxDepth-1);

    for (int i = 0; i < m_mesh->triangles.size(); i++){
        insertTriangle(m_mesh->triangles.at(i));
    }

    cout << "done building octtree: "<< t.restart() << "ms" << endl;
}
示例#28
0
void PainterBezier::paint(QPainter * painter)
{
    painter->setBrush(Qt::transparent);
    QRectF rect = calculateBoundingBox();
    setX(rect.topLeft().x() - 10);
    setY( rect.topLeft().y() - 10);
    setWidth( rect.width() + 20);
    setHeight( rect.height() + 20);
    QPen pen;
    pen.setWidthF(m_OutlineWidth);
    pen.setBrush(m_OutlineColor);
    painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    painter->setPen(pen);
    painter->setBrush(m_FillColor);
    QPainterPath bezierPath;
    QPointF pos(x(),y());
    bezierPath.moveTo(m_p1 - pos);
    bezierPath.cubicTo( m_p2 - pos, m_p3 - pos, m_p4 - pos );
    QPainterPathStroker outliner;
    outliner.setWidth(m_FillWidth);
    outliner.setCapStyle( Qt::FlatCap );
    m_Path = outliner.createStroke(bezierPath);
    painter->drawPath(m_Path);
}
示例#29
0
  void initializeInteractiveMarker() {
    visualization_msgs::InteractiveMarker int_marker;
    int_marker.header.frame_id = latest_pose_.header.frame_id;
    int_marker.name = "marker";
    int_marker.pose = geometry_msgs::Pose(latest_pose_.pose);
    
    visualization_msgs::Marker object_marker;
    if(object_type_ == std::string("cube")){
      object_marker.type = visualization_msgs::Marker::CUBE;
      object_marker.scale.x = object_x_;
      object_marker.scale.y = object_y_;
      object_marker.scale.z = object_z_;
      object_marker.color.r = object_r_;
      object_marker.color.g = object_g_;
      object_marker.color.b = object_b_;
      object_marker.color.a = object_a_;
      object_marker.pose.orientation.w = 1.0;
    }
    else if( object_type_ == std::string("sphere") ){
      object_marker.type = visualization_msgs::Marker::SPHERE;
      object_marker.scale.x = object_x_;
      object_marker.scale.y = object_y_;
      object_marker.scale.z = object_z_;
      object_marker.color.r = object_r_;
      object_marker.color.g = object_g_;
      object_marker.color.b = object_b_;
      object_marker.color.a = object_a_;
      object_marker.pose.orientation.w = 1.0;
    }else if(object_type_ == std::string("line")){
      object_marker.type = visualization_msgs::Marker::LINE_LIST;
      object_marker.scale.x = line_width_;
      object_marker.color.g = object_g_;
      object_marker.color.b = object_b_;
      object_marker.color.a = object_a_;
      object_marker.pose.orientation.w = 1.0;
      calculateBoundingBox(object_marker);
    }

    
    visualization_msgs::InteractiveMarkerControl object_marker_control;
    object_marker_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
    object_marker_control.always_visible = true;
    object_marker_control.markers.push_back(object_marker);
    int_marker.controls.push_back(object_marker_control);
  
    visualization_msgs::InteractiveMarkerControl control;
  
    control.orientation.w = 1;
    control.orientation.x = 1;
    control.orientation.y = 0;
    control.orientation.z = 0;
    if (show_6dof_circle_) {
      control.name = "rotate_x";
      control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
      int_marker.controls.push_back(control);
    }
    control.name = "move_x";
    control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
    int_marker.controls.push_back(control);

    control.orientation.w = 1;
    control.orientation.x = 0;
    control.orientation.y = 1;
    control.orientation.z = 0;
    if (show_6dof_circle_) {
      control.name = "rotate_z";
      control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
      int_marker.controls.push_back(control);
    }
    control.name = "move_z";
    control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
    int_marker.controls.push_back(control);

    control.orientation.w = 1;
    control.orientation.x = 0;
    control.orientation.y = 0;
    control.orientation.z = 1;
    if (show_6dof_circle_) {
      control.name = "rotate_y";
      control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
      int_marker.controls.push_back(control);
    }
    control.name = "move_y";
    control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
    int_marker.controls.push_back(control);
  
    int_marker.scale = std::max(object_x_, std::max(object_y_, object_z_)) + 0.5;

    server_->insert(int_marker,
                    boost::bind(&Marker6DOF::processFeedbackCB, this, _1));
    
    menu_handler_.apply(*server_, "marker");
    server_->applyChanges();
  }
示例#30
0
void
loadMeshes( CalCoreModel* calCoreModel,
            MeshesVector& meshes )
    throw (std::runtime_error)
{
    const int maxVertices = Constants::MAX_VERTEX_PER_MODEL;
    const int maxFaces    = Constants::MAX_VERTEX_PER_MODEL * 3;

    std::auto_ptr< CalHardwareModel > calHardwareModel( new CalHardwareModel( calCoreModel ) );
    
    osg::ref_ptr< VertexBuffer >      vertexBuffer( new VertexBuffer( maxVertices ) );
    osg::ref_ptr< WeightBuffer >      weightBuffer( new WeightBuffer( maxVertices ) );
    osg::ref_ptr< MatrixIndexBuffer > matrixIndexBuffer( new MatrixIndexBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      normalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      tangentBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< NormalBuffer >      binormalBuffer( new NormalBuffer( maxVertices ) );
    osg::ref_ptr< TexCoordBuffer >    texCoordBuffer( new TexCoordBuffer( maxVertices ) );
    std::vector< CalIndex >           indexBuffer( maxFaces*3 );

    std::vector< float > floatMatrixIndexBuffer( maxVertices*4 );

    calHardwareModel->setVertexBuffer((char*)vertexBuffer->getDataPointer(),
                                      3*sizeof(float));
#ifdef OSG_CAL_BYTE_BUFFERS
    std::vector< float > floatNormalBuffer( getVertexCount()*3 );
    calHardwareModel->setNormalBuffer((char*)&floatNormalBuffer.begin(),
                                      3*sizeof(float));
#else
    calHardwareModel->setNormalBuffer((char*)normalBuffer->getDataPointer(),
                                      3*sizeof(float));
#endif
    calHardwareModel->setWeightBuffer((char*)weightBuffer->getDataPointer(),
                                      4*sizeof(float));
    calHardwareModel->setMatrixIndexBuffer((char*)&floatMatrixIndexBuffer.front(),
                                           4*sizeof(float));
    calHardwareModel->setTextureCoordNum( 1 );
    calHardwareModel->setTextureCoordBuffer(0, // texture stage #
                                            (char*)texCoordBuffer->getDataPointer(),
                                            2*sizeof(float));
    calHardwareModel->setIndexBuffer( &indexBuffer.front() );
    // calHardwareModel->setCoreMeshIds(_activeMeshes);
    // if ids not set all meshes will be used at load() time

    //std::cout << "calHardwareModel->load" << std::endl;
    calHardwareModel->load( 0, 0, Constants::MAX_BONES_PER_MESH );
    //std::cout << "calHardwareModel->load ok" << std::endl;

    int vertexCount = calHardwareModel->getTotalVertexCount();
//    int faceCount   = calHardwareModel->getTotalFaceCount();

//    std::cout << "vertexCount = " << vertexCount << "; faceCount = " << faceCount << std::endl;
    
    GLubyte* matrixIndexBufferData = (GLubyte*) matrixIndexBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*4; i++ )
    {
        matrixIndexBufferData[i] = static_cast< GLubyte >( floatMatrixIndexBuffer[i] );
    }

#ifdef OSG_CAL_BYTE_BUFFERS
    GLbyte* normals = (GLbyte*) normalBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*3; i++ )
    {
        normals[i]  = static_cast< GLbyte >( floatNormalBuffer[i]*127.0 );
    }
#endif

    // invert UVs for OpenGL (textures are inverted otherwise - for example, see abdulla/klinok)
    GLfloat* texCoordBufferData = (GLfloat*) texCoordBuffer->getDataPointer();

    for ( float* tcy = texCoordBufferData + 1;
          tcy < texCoordBufferData + 2*vertexCount;
          tcy += 2 )
    {
        *tcy = 1.0f - *tcy;
    }

    // -- And now create meshes data --
    int unriggedBoneIndex = calCoreModel->getCoreSkeleton()->getVectorCoreBone().size();
    // we add empty bone in ModelData to handle unrigged vertices;
    
    for( int hardwareMeshId = 0; hardwareMeshId < calHardwareModel->getHardwareMeshCount(); hardwareMeshId++ )
    {
        calHardwareModel->selectHardwareMesh(hardwareMeshId);
        int faceCount = calHardwareModel->getFaceCount();

        if ( faceCount == 0 )
        {
            continue; // we ignore empty meshes
        }
        
        CalHardwareModel::CalHardwareMesh* hardwareMesh =
            &calHardwareModel->getVectorHardwareMesh()[ hardwareMeshId ];

        osg::ref_ptr< MeshData > m( new MeshData );
        
        m->name = calCoreModel->getCoreMesh( hardwareMesh->meshId )->getName();
        m->coreMaterial = hardwareMesh->pCoreMaterial;
        if ( m->coreMaterial == NULL )
        {
            CalCoreMesh*    coreMesh    = calCoreModel->getCoreMesh( hardwareMesh->meshId );
            CalCoreSubmesh* coreSubmesh = coreMesh->getCoreSubmesh( hardwareMesh->submeshId );
            // hardwareMesh->pCoreMaterial =
            //   coreModel->getCoreMaterial( coreSubmesh->getCoreMaterialThreadId() );
            char buf[ 1024 ];
            snprintf( buf, 1024,
                      "pCoreMaterial == NULL for mesh '%s' (mesh material id = %d), verify your mesh file data",
                      m->name.c_str(),
                      coreSubmesh->getCoreMaterialThreadId() );
            throw std::runtime_error( buf );
        }

        // -- Create index buffer --
        int indexesCount = faceCount * 3;
        int startIndex = calHardwareModel->getStartIndex();

        if ( indexesCount <= 0x100 )
        {
            m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLubyte* data = (GLubyte*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLubyte)*i++;
            }
        }
        else if ( indexesCount <= 0x10000 )
        {
            m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLushort* data = (GLushort*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLushort)*i++;
            }
        }
        else
        {
            m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, indexesCount );

            GLuint* data = (GLuint*)m->indexBuffer->getDataPointer();
            const CalIndex* i    = &indexBuffer[ startIndex ];
            const CalIndex* iEnd = &indexBuffer[ startIndex + indexesCount ];
            while ( i < iEnd )
            {
                *data++ = (GLuint)*i++;
            }
        }

        // -- Create other buffers --
        int vertexCount = calHardwareModel->getVertexCount();
        int baseVertexIndex = calHardwareModel->getBaseVertexIndex();

#define SUB_BUFFER( _type, _name )                                  \
        new _type( _name->begin() + baseVertexIndex,                \
                   _name->begin() + baseVertexIndex + vertexCount )
        
        m->vertexBuffer = SUB_BUFFER( VertexBuffer, vertexBuffer );
        m->weightBuffer = SUB_BUFFER( WeightBuffer, weightBuffer );
        m->matrixIndexBuffer = SUB_BUFFER( MatrixIndexBuffer, matrixIndexBuffer );
        m->normalBuffer = SUB_BUFFER( NormalBuffer, normalBuffer );
        m->texCoordBuffer = SUB_BUFFER( TexCoordBuffer, texCoordBuffer );

        // -- Parameters and buffers setup --
        m->boundingBox = calculateBoundingBox( m->vertexBuffer.get() );

        m->bonesIndices = hardwareMesh->m_vectorBonesIndices;

        checkRigidness( m.get(), unriggedBoneIndex );
        checkForEmptyTexCoord( m.get() );
        generateTangentAndHandednessBuffer( m.get(), &indexBuffer[ startIndex ] );

        meshes.push_back( m.get() );
    }
}