* brushexport plugin: write Kd (diffuse color) and map_Kd (diffuse map) data to .mtl
* brushexport plugin fix: invert Y during YZ swap; invert V of UV coords (correct texturing) * brushexport plugin: default to 'Don't collapse' option q3map2: * obj export: save in popular 'Y = Up, -Z = Forward' format * picomodel::obj: load as popular 'Y = Up, -Z = Forward' format * picomodel::obj: fix support of back references in faces
This commit is contained in:
parent
e7fbe45319
commit
034f06f18d
|
|
@ -178,7 +178,11 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
|
|
||||||
std::string mtlFile = objFile.substr( 0, objFile.length() - 4 ) + ".mtl";
|
std::string mtlFile = objFile.substr( 0, objFile.length() - 4 ) + ".mtl";
|
||||||
|
|
||||||
std::set<std::string> materials;
|
typedef std::pair<std::string, Colour3> Material;
|
||||||
|
auto materials_comparator = []( const Material& ma1, const Material& ma2 ) {
|
||||||
|
return ma1.first < ma2.first;
|
||||||
|
};
|
||||||
|
auto materials = std::set<Material, decltype( materials_comparator )>( materials_comparator );
|
||||||
|
|
||||||
TextFileOutputStream out( objFile.c_str() );
|
TextFileOutputStream out( objFile.c_str() );
|
||||||
|
|
||||||
|
|
@ -218,7 +222,7 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
// material
|
// material
|
||||||
if ( expmat && mode == COLLAPSE_ALL ) {
|
if ( expmat && mode == COLLAPSE_ALL ) {
|
||||||
out << "usemtl material" << "\n\n";
|
out << "usemtl material" << "\n\n";
|
||||||
materials.insert( "material" );
|
materials.insert( std::make_pair( std::string( "material" ), Colour3( 0.5, 0.5, 0.5 ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::list<const Face*>::const_iterator it( git->faces.begin() ); it != end; ++it )
|
for ( std::list<const Face*>::const_iterator it( git->faces.begin() ); it != end; ++it )
|
||||||
|
|
@ -226,8 +230,12 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
const Winding& w( ( *it )->getWinding() );
|
const Winding& w( ( *it )->getWinding() );
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
for ( size_t i = 0; i < w.numpoints; ++i )
|
size_t i = w.numpoints;
|
||||||
out << "v " << FloatFormat( w[i].vertex.x(), 1, 6 ) << " " << FloatFormat( w[i].vertex.z(), 1, 6 ) << " " << FloatFormat( w[i].vertex.y(), 1, 6 ) << "\n";
|
do{
|
||||||
|
--i;
|
||||||
|
out << "v " << FloatFormat( w[i].vertex.x(), 1, 6 ) << " " << FloatFormat( w[i].vertex.z(), 1, 6 ) << " " << FloatFormat( -w[i].vertex.y(), 1, 6 ) << "\n";
|
||||||
|
}
|
||||||
|
while( i != 0 );
|
||||||
}
|
}
|
||||||
out << "\n";
|
out << "\n";
|
||||||
|
|
||||||
|
|
@ -236,8 +244,12 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
const Winding& w( ( *it )->getWinding() );
|
const Winding& w( ( *it )->getWinding() );
|
||||||
|
|
||||||
// texcoords
|
// texcoords
|
||||||
for ( size_t i = 0; i < w.numpoints; ++i )
|
size_t i = w.numpoints;
|
||||||
out << "vt " << FloatFormat( w[i].texcoord.x(), 1, 6 ) << " " << FloatFormat( w[i].texcoord.y(), 1, 6 ) << "\n";
|
do{
|
||||||
|
--i;
|
||||||
|
out << "vt " << FloatFormat( w[i].texcoord.x(), 1, 6 ) << " " << FloatFormat( -w[i].texcoord.y(), 1, 6 ) << "\n";
|
||||||
|
}
|
||||||
|
while( i != 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( std::list<const Face*>::const_iterator it( git->faces.begin() ); it != end; ++it )
|
for ( std::list<const Face*>::const_iterator it( git->faces.begin() ); it != end; ++it )
|
||||||
|
|
@ -247,18 +259,24 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
// faces
|
// faces
|
||||||
StringOutputStream faceLine( 256 );
|
StringOutputStream faceLine( 256 );
|
||||||
faceLine << "\nf";
|
faceLine << "\nf";
|
||||||
for ( size_t i = 0; i < w.numpoints; ++i, ++vertex_count )
|
|
||||||
{
|
size_t i = w.numpoints;
|
||||||
faceLine << " " << vertex_count + 1 << "/" << vertex_count + 1;
|
do{
|
||||||
|
--i;
|
||||||
|
++vertex_count;
|
||||||
|
faceLine << " " << vertex_count << "/" << vertex_count;
|
||||||
}
|
}
|
||||||
|
while( i != 0 );
|
||||||
|
|
||||||
if ( mode != COLLAPSE_ALL ) {
|
if ( mode != COLLAPSE_ALL ) {
|
||||||
materials.insert( ( *it )->getShader().getShader() );
|
materials.insert( std::make_pair( std::string( ( *it )->getShader().getShader() ), ( *it )->getShader().state()->getTexture().color ) );
|
||||||
brushMaterials.insert( String_Pair( ( *it )->getShader().getShader(), faceLine.c_str() ) );
|
brushMaterials.insert( String_Pair( ( *it )->getShader().getShader(), faceLine.c_str() ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out << faceLine.c_str();
|
out << faceLine.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mode != COLLAPSE_ALL ) {
|
if ( mode != COLLAPSE_ALL ) {
|
||||||
|
|
@ -297,14 +315,19 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
|
||||||
|
|
||||||
outMtl << "# Wavefront material file exported with NetRadiants brushexport plugin.\n";
|
outMtl << "# Wavefront material file exported with NetRadiants brushexport plugin.\n";
|
||||||
outMtl << "# Material Count: " << (const Unsigned)materials.size() << "\n\n";
|
outMtl << "# Material Count: " << (const Unsigned)materials.size() << "\n\n";
|
||||||
for ( std::set<std::string>::const_iterator it( materials.begin() ); it != materials.end(); ++it )
|
for ( std::set<std::pair<std::string, Colour3>>::const_iterator it( materials.begin() ); it != materials.end(); ++it )
|
||||||
{
|
{
|
||||||
if ( limNames && it->size() > MAX_MATERIAL_NAME ) {
|
const std::string& str = it->first;
|
||||||
outMtl << "newmtl " << it->substr( it->size() - MAX_MATERIAL_NAME, it->size() ).c_str() << "\n";
|
const Colour3& clr = it->second;
|
||||||
|
if ( limNames && str.size() > MAX_MATERIAL_NAME ) {
|
||||||
|
outMtl << "newmtl " << str.substr( str.size() - MAX_MATERIAL_NAME, str.size() ).c_str() << "\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outMtl << "newmtl " << it->c_str() << "\n";
|
outMtl << "newmtl " << str.c_str() << "\n";
|
||||||
}
|
}
|
||||||
|
outMtl << "Kd " << clr.x() << " " << clr.y() << " " << clr.z() << "\n";
|
||||||
|
outMtl << "map_Kd " << str.c_str() << "\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,6 +343,7 @@ ForEachFace( ExportData& _exporter )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void visit( Face& face ) const {
|
void visit( Face& face ) const {
|
||||||
|
if( face.contributes() )
|
||||||
exporter.AddBrushFace( face );
|
exporter.AddBrushFace( face );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ create_w_plugplug2( void ){
|
||||||
gtk_box_pack_start( GTK_BOX( vbox4 ), r_nocollapse, FALSE, FALSE, 0 );
|
gtk_box_pack_start( GTK_BOX( vbox4 ), r_nocollapse, FALSE, FALSE, 0 );
|
||||||
gtk_radio_button_set_group( GTK_RADIO_BUTTON( r_nocollapse ), r_collapse_group );
|
gtk_radio_button_set_group( GTK_RADIO_BUTTON( r_nocollapse ), r_collapse_group );
|
||||||
r_collapse_group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( r_nocollapse ) );
|
r_collapse_group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( r_nocollapse ) );
|
||||||
|
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( r_nocollapse ), TRUE );
|
||||||
|
|
||||||
vbox3 = gtk_vbox_new( FALSE, 0 );
|
vbox3 = gtk_vbox_new( FALSE, 0 );
|
||||||
gtk_widget_set_name( vbox3, "vbox3" );
|
gtk_widget_set_name( vbox3, "vbox3" );
|
||||||
|
|
|
||||||
|
|
@ -779,17 +779,15 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* fix useless back references */
|
/* fix useless back references */
|
||||||
/* todo: check if this works as it is supposed to */
|
|
||||||
|
|
||||||
/* assign new indices */
|
/* assign new indices */
|
||||||
if ( iv [ i ] < 0 ) {
|
if ( iv [ i ] < 0 ) {
|
||||||
iv [ i ] = ( numVerts - iv [ i ] );
|
iv [ i ] = ( numVerts + iv [ i ] + 1 );
|
||||||
}
|
}
|
||||||
if ( ivt[ i ] < 0 ) {
|
if ( ivt[ i ] < 0 ) {
|
||||||
ivt[ i ] = ( numUVs - ivt[ i ] );
|
ivt[ i ] = ( numUVs + ivt[ i ] + 1 );
|
||||||
}
|
}
|
||||||
if ( ivn[ i ] < 0 ) {
|
if ( ivn[ i ] < 0 ) {
|
||||||
ivn[ i ] = ( numNormals - ivn[ i ] );
|
ivn[ i ] = ( numNormals + ivn[ i ] + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validate indices */
|
/* validate indices */
|
||||||
|
|
@ -807,8 +805,8 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
||||||
|
|
||||||
/* get vertex data */
|
/* get vertex data */
|
||||||
verts[ i ][ 0 ] = vertexData[ iv[ i ] - 1 ].v[ 0 ];
|
verts[ i ][ 0 ] = vertexData[ iv[ i ] - 1 ].v[ 0 ];
|
||||||
verts[ i ][ 1 ] = vertexData[ iv[ i ] - 1 ].v[ 1 ];
|
verts[ i ][ 1 ] = -vertexData[ iv[ i ] - 1 ].v[ 2 ];
|
||||||
verts[ i ][ 2 ] = vertexData[ iv[ i ] - 1 ].v[ 2 ];
|
verts[ i ][ 2 ] = vertexData[ iv[ i ] - 1 ].v[ 1 ];
|
||||||
}
|
}
|
||||||
/* set vertex normal */
|
/* set vertex normal */
|
||||||
if ( has_vn ) {
|
if ( has_vn ) {
|
||||||
|
|
@ -819,8 +817,8 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
||||||
|
|
||||||
/* get normal data */
|
/* get normal data */
|
||||||
normals[ i ][ 0 ] = vertexData[ ivn[ i ] - 1 ].vn[ 0 ];
|
normals[ i ][ 0 ] = vertexData[ ivn[ i ] - 1 ].vn[ 0 ];
|
||||||
normals[ i ][ 1 ] = vertexData[ ivn[ i ] - 1 ].vn[ 1 ];
|
normals[ i ][ 1 ] = -vertexData[ ivn[ i ] - 1 ].vn[ 2 ];
|
||||||
normals[ i ][ 2 ] = vertexData[ ivn[ i ] - 1 ].vn[ 2 ];
|
normals[ i ][ 2 ] = vertexData[ ivn[ i ] - 1 ].vn[ 1 ];
|
||||||
}
|
}
|
||||||
/* set texture coordinate */
|
/* set texture coordinate */
|
||||||
if ( has_vt ) {
|
if ( has_vt ) {
|
||||||
|
|
@ -831,8 +829,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
||||||
|
|
||||||
/* get uv coord data */
|
/* get uv coord data */
|
||||||
coords[ i ][ 0 ] = vertexData[ ivt[ i ] - 1 ].vt[ 0 ];
|
coords[ i ][ 0 ] = vertexData[ ivt[ i ] - 1 ].vt[ 0 ];
|
||||||
coords[ i ][ 1 ] = vertexData[ ivt[ i ] - 1 ].vt[ 1 ];
|
coords[ i ][ 1 ] = -vertexData[ ivt[ i ] - 1 ].vt[ 1 ];
|
||||||
coords[ i ][ 1 ] = -coords[ i ][ 1 ];
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_PM_OBJ_EX
|
#ifdef DEBUG_PM_OBJ_EX
|
||||||
printf( "(%4d",iv[ i ] );
|
printf( "(%4d",iv[ i ] );
|
||||||
|
|
@ -852,10 +849,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
||||||
/* read the actual data we need to assign all the crap */
|
/* read the actual data we need to assign all the crap */
|
||||||
/* to our current pico surface */
|
/* to our current pico surface */
|
||||||
if ( has_v ) {
|
if ( has_v ) {
|
||||||
int max = 3;
|
const int max = have_quad? 4 : 3;
|
||||||
if ( have_quad ) {
|
|
||||||
max = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* assign all surface information */
|
/* assign all surface information */
|
||||||
for ( i = 0; i < max; i++ )
|
for ( i = 0; i < max; i++ )
|
||||||
|
|
|
||||||
|
|
@ -98,13 +98,13 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr
|
||||||
v = i + ds->firstVert;
|
v = i + ds->firstVert;
|
||||||
dv = &bspDrawVerts[ v ];
|
dv = &bspDrawVerts[ v ];
|
||||||
fprintf( f, "# vertex %d\r\n", i + objVertexCount + 1 );
|
fprintf( f, "# vertex %d\r\n", i + objVertexCount + 1 );
|
||||||
fprintf( f, "v %f %f %f\r\n", dv->xyz[ 0 ], dv->xyz[ 1 ], dv->xyz[ 2 ] );
|
fprintf( f, "v %f %f %f\r\n", dv->xyz[ 0 ], dv->xyz[ 2 ], -dv->xyz[ 1 ] );
|
||||||
fprintf( f, "vn %f %f %f\r\n", dv->normal[ 0 ], dv->normal[ 1 ], dv->normal[ 2 ] );
|
fprintf( f, "vn %f %f %f\r\n", dv->normal[ 0 ], dv->normal[ 2 ], -dv->normal[ 1 ] );
|
||||||
if ( lightmapsAsTexcoord ) {
|
if ( lightmapsAsTexcoord ) {
|
||||||
fprintf( f, "vt %f %f\r\n", dv->lightmap[0][0], 1.0 - dv->lightmap[0][1] );
|
fprintf( f, "vt %f %f\r\n", dv->lightmap[0][0], -dv->lightmap[0][1] );
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
fprintf( f, "vt %f %f\r\n", dv->st[ 0 ], 1.0 - dv->st[ 1 ] );
|
fprintf( f, "vt %f %f\r\n", dv->st[ 0 ], -dv->st[ 1 ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user