Example #1
0
FBXLoader::FBXLoader(const char *filename)
{
  m_error = true;
  if (m_fbx_sdk_manager == nullptr)
  {
    m_fbx_sdk_manager = FbxManager::Create();
    m_fbx_sdk_manager->SetIOSettings(FbxIOSettings::Create(m_fbx_sdk_manager, IOSROOT));
  }
  FbxImporter *importer = FbxImporter::Create(m_fbx_sdk_manager, "");
  FbxScene *scene = FbxScene::Create(m_fbx_sdk_manager, "");
  if (!importer->Initialize(filename, -1, m_fbx_sdk_manager->GetIOSettings()))
    return;
  if (!importer->Import(scene))
    return;
  importer->Destroy();

  FbxNode *root_node = scene->GetRootNode();
  if (root_node)
  {
    for (int i = 0; i < root_node->GetChildCount(); i++)
    {
      FbxNode *child_node = root_node->GetChild(i);
      if (child_node->GetNodeAttribute() == NULL)
        continue;

      FbxNodeAttribute::EType type = child_node->GetNodeAttribute()->GetAttributeType();
      if (type != FbxNodeAttribute::eMesh)
        continue;

      FbxMesh *mesh = (FbxMesh *) child_node->GetNodeAttribute();
      FbxVector4 *vertices = mesh->GetControlPoints();
      for (int j = 0; j < mesh->GetPolygonCount(); j++)
      {
        int num_verts = mesh->GetPolygonSize(j);
        assert(num_verts == 3);
        DirectX::XMFLOAT3 vertex[3];
        FbxVector4 polygon_normal(0, 0, 0);

        for (int k = 0; k < num_verts; k++)
        {
          int control_point_idx = mesh->GetPolygonVertex(j, k);
          FbxVector4 vertex_normal;
          mesh->GetPolygonVertexNormal(j, k, vertex_normal);
          polygon_normal += vertex_normal;
          vertex[k].x = (float) vertices[control_point_idx].mData[0];
          vertex[k].y = (float) vertices[control_point_idx].mData[1];
          vertex[k].z = (float) vertices[control_point_idx].mData[2];
        }

        if (IsClockwise(vertex, num_verts, polygon_normal))
        {
          for (int i = 0; i < num_verts; i++)
            m_vertices.push_back(ToD3DCoordinateSystem(vertex[i]));
        }
        else
        {
          for (int i = 0; i < num_verts; i++)
            m_vertices.push_back(ToD3DCoordinateSystem(vertex[num_verts - 1 - i]));
        }
      }
    }
  }

  for (size_t i = 0; i < m_vertices.size(); i++)
    m_indices.push_back(i);

  m_error = false;
}
Example #2
0
void bsp_tree_create_from_solid(struct BspTree* tree, struct Solid* solid) {
    size_t alloc_attributes_result = bsp_tree_alloc_attributes(tree, solid->attributes_size);
    log_assert( alloc_attributes_result >= solid->attributes_size );

    size_t num_polygons = solid->indices_size/3;
    size_t alloc_polygons_result = bsp_tree_alloc_polygons(tree, num_polygons);
    log_assert( alloc_polygons_result >= num_polygons );

    size_t alloc_nodes_result = bsp_tree_alloc_nodes(tree, num_polygons);
    log_assert( alloc_nodes_result >= num_polygons );

    int32_t* workset_polygons_front = malloc(alloc_polygons_result * sizeof(int32_t));
    log_assert( workset_polygons_front != NULL );
    int32_t* workset_polygons_back = malloc(alloc_polygons_result * sizeof(int32_t));
    log_assert( workset_polygons_back != NULL );

    float min_x = FLT_MAX;
    float min_y = FLT_MAX;
    float min_z = FLT_MAX;
    float max_x = -FLT_MAX;
    float max_y = -FLT_MAX;
    float max_z = -FLT_MAX;
    for( size_t indices_i = 0; indices_i < solid->indices_size+1; indices_i++ ) {
        uint32_t src_i = solid->indices[indices_i];

        if( indices_i < solid->indices_size ) {
            VecP* src = &solid->vertices[src_i*VERTEX_SIZE];
            VecP* dst = &tree->attributes.vertices[indices_i*VERTEX_SIZE];
            vec_copy3f(src, dst);
            tree->attributes.occupied += 1;

            if( src[0] < min_x ) {
                min_x = src[0];
            }
            if( src[1] < min_y ) {
                min_y = src[1];
            }
            if( src[2] < min_z ) {
                min_z = src[2];
            }

            if( src[0] > max_x ) {
                max_x = src[0];
            }
            if( src[1] > max_y ) {
                max_y = src[1];
            }
            if( src[2] > max_z ) {
                max_z = src[2];
            }
        }

        if( indices_i > 0 && indices_i % 3 == 0 ) {
            size_t poly_i = indices_i / 3 - 1;
            tree->polygons.array[poly_i].start = poly_i*3*VERTEX_SIZE;
            tree->polygons.array[poly_i].size = 3;
            polygon_normal(3, VERTEX_SIZE, &tree->attributes.vertices[poly_i*3*VERTEX_SIZE], tree->polygons.array[poly_i].normal);
            tree->polygons.occupied += 1;

            workset_polygons_front[poly_i] = poly_i;
        }

    }

    struct BspNode* root = &tree->nodes.array[0];
    bsp_node_create(root);
    tree->nodes.occupied = 1;
    root->bounds.half_width = (max_x - min_x)/2.0f;
    root->bounds.half_height = (max_y - min_y)/2.0f;
    root->bounds.half_depth = (max_z - min_z)/2.0f;
    root->bounds.center[0] = min_x + root->bounds.half_width;
    root->bounds.center[1] = min_y + root->bounds.half_height;
    root->bounds.center[2] = min_z + root->bounds.half_depth;

    root->divider = 0;    bsp_select_balanced_divider(tree, root, num_polygons, workset_polygons_front, &root->divider);

    struct BspPoly* root_divider = &tree->polygons.array[root->divider];
    const float* root_divider_polygon = &tree->attributes.vertices[root_divider->start];

    draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 0, 255}, 0.01f, root_divider->size, root_divider_polygon, root_divider->normal);
    draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 0, 255}, 0.01f, root_divider->normal, &root_divider_polygon[3], 1.0f, 0.1f);
    /* draw_plane(&global_static_canvas, MAX_CANVAS_LAYERS-1, (Mat)IDENTITY_MAT, (Color){120, 120, 150, 127}, root_divider->normal, &root_divider_polygon[3], 10.0f); */

    for( size_t polygon_i = 0; polygon_i < num_polygons; polygon_i++ ) {
        size_t cuts_polygon_size = 3;
        const float* cuts_polygon = &tree->attributes.vertices[polygon_i*cuts_polygon_size*VERTEX_SIZE];

        size_t result_size = cuts_polygon_size;
        struct PolygonCutPoints result_points[cuts_polygon_size];
        enum PolygonCutType result_type = polygon_cut(cuts_polygon_size, VERTEX_SIZE, cuts_polygon,
                                                      root_divider->normal, root_divider_polygon,
                                                      result_size, result_points);

        Vec3f cuts_polygon_normal = {0};
        polygon_normal(3, VERTEX_SIZE, cuts_polygon, cuts_polygon_normal);
        switch(result_type) {
            case POLYGON_COPLANNAR:
                //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal);
                break;
            case POLYGON_FRONT:
                //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal);
                break;
            case POLYGON_BACK:
                //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){0, 0, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal);
                break;
            case POLYGON_SPANNING:
                //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 0, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal);

                if( result_points[0].num_cuts > 0 ) {
                    size_t new_poly_size = cuts_polygon_size+result_points[0].num_cuts+10;

                    size_t front_occupied = 0;
                    float front_vertices[new_poly_size*VERTEX_SIZE];

                    size_t back_occupied = 0;
                    float back_vertices[new_poly_size*VERTEX_SIZE];

                    for( size_t result_i = 0; result_i < result_size; result_i++ ) {
                        if( result_points[result_i].type == POLYGON_BACK ) {
                            vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &back_vertices[back_occupied*VERTEX_SIZE]);
                            back_occupied += 1;
                        } else if( result_points[result_i].type == POLYGON_FRONT ) {
                            vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &front_vertices[front_occupied*VERTEX_SIZE]);
                            front_occupied += 1;
                        } else if( result_points[result_i].type == POLYGON_COPLANNAR ) {
                            vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &back_vertices[back_occupied*VERTEX_SIZE]);
                            back_occupied += 1;
                            vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &front_vertices[front_occupied*VERTEX_SIZE]);
                            front_occupied += 1;
                        }

                        if( result_points[result_i].interpolation_index > -1 ) {
                            const VecP* a = &cuts_polygon[result_i*VERTEX_SIZE];
                            const VecP* b = &cuts_polygon[result_points[result_i].interpolation_index*VERTEX_SIZE];
                            Vec3f r = {0};
                            vec_lerp(b, a, result_points[result_i].interpolation_value, r);

                            vec_copy3f(r, &back_vertices[back_occupied*VERTEX_SIZE]);
                            back_occupied += 1;
                            vec_copy3f(r, &front_vertices[front_occupied*VERTEX_SIZE]);
                            front_occupied += 1;
                        }
                    }

                    //printf("front_occupied: %lu\n", front_occupied);
                    //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, red, 0.01f, front_occupied, front_vertices, cuts_polygon_normal);
                    //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, white, 0.01f, back_occupied, back_vertices, cuts_polygon_normal);
                }
                break;
        }
    }

    log_fail(__FILE__, __LINE__, "BUILT BSP TREE... OR NOT?\n");
}
Example #3
0
/**
 * メッシュ情報を読み込む
 *
 * @param mesh メッシュ情報
 */
void FbxFileLoader::load_mesh( FbxMesh* mesh )
{
	if ( ! mesh )
	{
		return;
	}

	if ( ! get_model()->get_mesh() )
	{
		get_model()->set_mesh( create_mesh() );
	}

	VertexIndexMap vertex_index_map;
	VertexList vertex_list;

	Mesh::PositionList position_list;
	Mesh::VertexWeightList vertex_weight_list;

	// load_mesh_vertex()
	for ( int n = 0; n < mesh->GetControlPointsCount(); n++ )
	{
		FbxVector4 v = mesh->GetControlPointAt( n );

		position_list.push_back(
			Mesh::Position(
				static_cast< float >( v[ 0 ] ),
				static_cast< float >( v[ 1 ] ),
				static_cast< float >( v[ 2 ] ) ) );
	}

	// load_mesh_vertex_weight()
	{
		int skin_count = mesh->GetDeformerCount( FbxDeformer::eSkin );

		if ( skin_count > 0 )
		{
			assert( skin_count == 1 );

			vertex_weight_list.resize( position_list.size() );

			FbxSkin* skin = FbxCast< FbxSkin >( mesh->GetDeformer( 0, FbxDeformer::eSkin ) );

			load_mesh_vertex_weight( skin, vertex_weight_list );
		}
	}

	FbxLayerElementSmoothing* smoothing = 0;

	// load_mesh_smoothing_info()
	{
		FbxLayer* layer = mesh->GetLayer( 0 );
		smoothing = layer->GetSmoothing();
	}

	if ( ! smoothing )
	{
		COMMON_THROW_EXCEPTION_MESSAGE( "this FBX format is not supported. ( no smoothing info )" );
	}

	// load_mesh_plygon()
	FbxLayerElementArrayTemplate< int >* material_indices;
	mesh->GetMaterialIndices( & material_indices );

	for ( int n = 0; n < mesh->GetPolygonCount(); n++ )
	{
		Mesh::VertexGroup* vertex_group = get_model()->get_mesh()->get_vertex_group_at( material_indices->GetAt( n ) );

		bool is_smooth = smoothing->GetDirectArray().GetAt( n ) != 0;
		FbxVector4 polygon_normal( 0.f, 0.f, 0.f );

		if ( ! is_smooth )
		{
			// ポリゴンの法線を計算する
			Mesh::Position p1( position_list.at( mesh->GetPolygonVertex( n, 0 ) ) );
			Mesh::Position p2( position_list.at( mesh->GetPolygonVertex( n, 1 ) ) );
			Mesh::Position p3( position_list.at( mesh->GetPolygonVertex( n, 2 ) ) );

			FbxVector4 a = FbxVector4( p1.x(), p1.y(), p1.z() );
			FbxVector4 b = FbxVector4( p2.x(), p2.y(), p2.z() );
			FbxVector4 c = FbxVector4( p3.x(), p3.y(), p3.z() );

			FbxVector4 ab( b - a );
			FbxVector4 bc( c - b );

			polygon_normal = ab.CrossProduct( bc );
			polygon_normal.Normalize();
		}

		for ( int m = 0; m < mesh->GetPolygonSize( n ); m++ )
		{
			int position_index = mesh->GetPolygonVertex( n, m );

			Mesh::Vertex v;
			v.Position = Mesh::Position( position_list.at( position_index ) );

			FbxVector2 uv_vector;
			bool unmapped;
			
			if ( mesh->GetPolygonVertexUV( n, m, "UVMap", uv_vector, unmapped) )
			{
				v.TexCoord = Mesh::TexCoord(
					static_cast< float >( uv_vector[ 0 ] ),
					1.f - static_cast< float >( uv_vector[ 1 ] ) );
			}

			if ( is_smooth )
			{
				FbxVector4 normal_vector;

				// 頂点の法線
				if ( mesh->GetPolygonVertexNormal( n, m, normal_vector ) )
				{
					v.Normal = Mesh::Normal(
						static_cast< float >( normal_vector[ 0 ] ),
						static_cast< float >( normal_vector[ 1 ] ),
						static_cast< float >( normal_vector[ 2 ] ) );
				}
			}
			else
			{
				// ポリゴンの法線
				v.Normal = Mesh::Normal(
					static_cast< float >( polygon_normal[ 0 ] ),
					static_cast< float >( polygon_normal[ 1 ] ),
					static_cast< float >( polygon_normal[ 2 ] ) );
			}
			
			// 頂点の一覧に追加
			{
				VertexIndexMap::iterator i = vertex_index_map.find( v );

				if ( i != vertex_index_map.end() )
				{
					vertex_group->add_index( i->second );
				}
				else
				{
					Mesh::Index vertex_index = static_cast< Mesh::Index >( get_model()->get_mesh()->get_vertex_count() );

					get_model()->get_mesh()->add_vertex( v );

					if ( ! vertex_weight_list.empty() )
					{
						get_model()->get_mesh()->add_vertex_weight( vertex_weight_list.at( position_index ) );
					}

					vertex_group->add_index( vertex_index );

					vertex_index_map[ v ] = vertex_index;
				}
			}
		}
	}
}