📄 daewgeometry.cpp
字号:
/* * Copyright 2006 Sony Computer Entertainment Inc. * * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this * file except in compliance with the License. You may obtain a copy of the License at: * http://research.scea.com/scea_shared_source_license.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing permissions and limitations under the * License. */#include "daeWriter.h"#include <dom/domCOLLADA.h>#include <dom/domNode.h>#include <dom/domLibrary_geometries.h>#include <dom/domSource.h>#include <dom/domGeometry.h>#include <dom/domConstants.h>#include <sstream>using namespace osgdae;//GEODEvoid daeWriter::apply( osg::Geode &node ){#ifdef _DEBUG debugPrint( node );#endif pushStateSet(node.getStateSet()); if (NULL != node.getStateSet()) m_CurrentRenderingHint = node.getStateSet()->getRenderingHint(); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *g = node.getDrawable( i )->asGeometry(); if ( g != NULL ) { pushStateSet(g->getStateSet()); std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g ); if ( iter != geometryMap.end() ) { domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) ); std::string url = "#" + std::string( iter->second->getId() ); ig->setUrl( url.c_str() ); if (!stateSetStack.empty()) processMaterial( currentStateSet.get(), ig, iter->second->getId() ); } else { if ( lib_geoms == NULL ) { lib_geoms = daeSafeCast< domLibrary_geometries >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) ); } std::string name = node.getName(); if ( name.empty() ) name = "geometry"; name = uniquify( name ); domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->createAndPlace( COLLADA_ELEMENT_GEOMETRY ) ); geo->setId( name.c_str() ); if ( !processGeometry( g, geo, name ) ) { daeElement::removeFromParent( geo ); continue; } domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) ); std::string url = "#" + name; ig->setUrl( url.c_str() );#ifndef EARTH_GEO geometryMap.insert( std::make_pair( g, geo ) );#endif if (!stateSetStack.empty()) processMaterial( currentStateSet.get(), ig, name ); } popStateSet(g->getStateSet()); } } lastVisited = GEODE; popStateSet(node.getStateSet());}/** append elements (verts, normals, colors and texcoord) for file write */void daeWriter::appendGeometryIndices(osg::Geometry *geom, domP * p, unsigned int vindex, domSource * norm, domSource * color, const ArrayNIndices & verts, const ArrayNIndices & normals, const ArrayNIndices & colors, const std::vector<ArrayNIndices> & texcoords, unsigned int ncount, unsigned int ccount){ p->getValue().append( verts.inds!=NULL?verts.inds->index( vindex ):vindex ); if ( norm != NULL ) if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX ) p->getValue().append( normals.inds!=NULL?normals.inds->index( vindex ):vindex ); else p->getValue().append( normals.inds!=NULL?normals.inds->index( ncount ):ncount ); if ( color != NULL ) if ( geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX ) p->getValue().append( colors.inds!=NULL?colors.inds->index( vindex ):vindex ); else p->getValue().append( colors.inds!=NULL?colors.inds->index( ccount ):ccount ); for ( unsigned int ti = 0; ti < texcoords.size(); ti++ ) { //ArrayNIndices &tc = texcoords[ti]; p->getValue().append( texcoords[ti].inds!=NULL?texcoords[ti].inds->index(vindex):vindex ); } } bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const std::string &name ){ domMesh *mesh = daeSafeCast< domMesh >( geo->createAndPlace( COLLADA_ELEMENT_MESH ) ); domSource *pos = NULL; domSource *norm = NULL; domSource *color = NULL; std::vector< domSource * >texcoord; domLines *lines = NULL; domLinestrips *linestrips = NULL; domTriangles *tris = NULL; domTristrips *tristrips = NULL; domTrifans *trifans = NULL; domPolygons *polys = NULL; domPolylist *polylist = NULL; //TODO: Make sure the assumptions about arrays is correct. // Probably not so I should make each thing more flexible so arrays can be different sizes. /*osg::Vec3Array *verts = (osg::Vec3Array *)geom->getVertexArray(); osg::IndexArray *vertInds = geom->getVertexIndices(); osg::Vec3Array *normals = (osg::Vec3Array *)geom->getNormalArray(); osg::IndexArray *normalInds = geom->getNormalIndices(); osg::Vec4Array *colors = (osg::Vec4Array *)geom->getColorArray(); osg::IndexArray *colorInds = geom->getColorIndices();*/ ArrayNIndices verts( geom->getVertexArray(), geom->getVertexIndices() ); ArrayNIndices normals( geom->getNormalArray(), geom->getNormalIndices() ); ArrayNIndices colors( geom->getColorArray(), geom->getColorIndices() ); std::vector<ArrayNIndices> texcoords; for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ ) { texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) ); } //process POSITION std::string sName = name + "-positions"; pos = createSource( mesh, sName, verts.mode ); switch( verts.mode ) { case ArrayNIndices::VEC2: pos->getFloat_array()->setCount( verts.vec2->size() *2 ); pos->getTechnique_common()->getAccessor()->setCount( verts.vec2->size() ); for ( unsigned int i = 0; i < verts.vec2->size(); i++ ) { pos->getFloat_array()->getValue().append( (*verts.vec2)[i].x() ); pos->getFloat_array()->getValue().append( (*verts.vec2)[i].y() ); } break; case ArrayNIndices::VEC3: pos->getFloat_array()->setCount( verts.vec3->size() *3 ); pos->getTechnique_common()->getAccessor()->setCount( verts.vec3->size() ); for ( unsigned int i = 0; i < verts.vec3->size(); i++ ) { pos->getFloat_array()->getValue().append( (*verts.vec3)[i].x() ); pos->getFloat_array()->getValue().append( (*verts.vec3)[i].y() ); pos->getFloat_array()->getValue().append( (*verts.vec3)[i].z() ); } break; case ArrayNIndices::VEC4: pos->getFloat_array()->setCount( verts.vec4->size() *4 ); pos->getTechnique_common()->getAccessor()->setCount( verts.vec4->size() ); for ( unsigned int i = 0; i < verts.vec4->size(); i++ ) { pos->getFloat_array()->getValue().append( (*verts.vec4)[i].x() ); pos->getFloat_array()->getValue().append( (*verts.vec4)[i].y() ); pos->getFloat_array()->getValue().append( (*verts.vec4)[i].z() ); pos->getFloat_array()->getValue().append( (*verts.vec4)[i].w() ); } break; default: osg::notify( osg::WARN ) << "Invalid array type for vertices" << std::endl; break; } //create a vertices element domVertices *vertices = daeSafeCast< domVertices >( mesh->createAndPlace( COLLADA_ELEMENT_VERTICES ) ); std::string vName = name + "-vertices"; vertices->setId( vName.c_str() ); //make a POSITION input in it domInputLocal *il = daeSafeCast< domInputLocal >( vertices->createAndPlace( "input" ) ); il->setSemantic( "POSITION" ); std::string url = "#" + std::string( pos->getId() ); il->setSource( url.c_str() ); //process NORMAL if ( normals.mode != ArrayNIndices::NONE ) { sName = name + "-normals"; norm = createSource( mesh, sName, normals.mode ); switch( normals.mode ) { case ArrayNIndices::VEC2: norm->getFloat_array()->setCount( normals.vec2->size() *2 ); norm->getTechnique_common()->getAccessor()->setCount( normals.vec2->size() ); for ( unsigned int i = 0; i < normals.vec2->size(); i++ ) { norm->getFloat_array()->getValue().append( (*normals.vec2)[i].x() ); norm->getFloat_array()->getValue().append( (*normals.vec2)[i].y() ); } break; case ArrayNIndices::VEC3: norm->getFloat_array()->setCount( normals.vec3->size() *3 ); norm->getTechnique_common()->getAccessor()->setCount( normals.vec3->size() ); for ( unsigned int i = 0; i < normals.vec3->size(); i++ ) { norm->getFloat_array()->getValue().append( (*normals.vec3)[i].x() ); norm->getFloat_array()->getValue().append( (*normals.vec3)[i].y() ); norm->getFloat_array()->getValue().append( (*normals.vec3)[i].z() ); } break; case ArrayNIndices::VEC4: norm->getFloat_array()->setCount( normals.vec4->size() *4 ); norm->getTechnique_common()->getAccessor()->setCount( normals.vec4->size() ); for ( unsigned int i = 0; i < normals.vec4->size(); i++ ) { norm->getFloat_array()->getValue().append( (*normals.vec4)[i].x() ); norm->getFloat_array()->getValue().append( (*normals.vec4)[i].y() ); norm->getFloat_array()->getValue().append( (*normals.vec4)[i].z() ); norm->getFloat_array()->getValue().append( (*normals.vec4)[i].w() ); } break; //no normals case ArrayNIndices::NONE: osg::notify( osg::WARN ) << "No array type for normals"<<std::endl; default: osg::notify( osg::WARN ) << "Invalid array type for normals"<<std::endl; break; } //if NORMAL shares same indices as POSITION put it in the vertices /*if ( normalInds == vertInds && vertInds != NULL ) { il = daeSafeCast< domInputLocal >( vertices->createAndPlace( "input" ) ); il->setSemantic( "NORMAL" ); url = "#" + std::string(md->norm->getId()); il->setSource( url.c_str() ); }*/ } //process COLOR if ( colors.mode != ArrayNIndices::NONE ) { sName = name + "-colors"; color = createSource( mesh, sName, colors.mode, true ); switch( colors.mode ) { case ArrayNIndices::VEC2: color->getFloat_array()->setCount( colors.vec2->size() *2 ); color->getTechnique_common()->getAccessor()->setCount( colors.vec2->size() ); for ( unsigned int i = 0; i < colors.vec2->size(); i++ ) { color->getFloat_array()->getValue().append( (*colors.vec2)[i].x() ); color->getFloat_array()->getValue().append( (*colors.vec2)[i].y() ); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -