Flutter Cube

repository·master·Indexed 42 days ago

https://github.com/zesage/flutter_cube

A Flutter widget for rendering 3D models using the Wavefront .obj file format. It provides a Cube widget for scene management, support for .mtl material files, and tools for handling 3D geometry through Mesh and Object classes. Features include interactive camera rotation and zooming, texture atlas packing, and support for parent-child object hierarchies.

Tokens
3.7K
Snippets
16
Records
19
Agent score
54%

What's inside Flutter Cube

  1. Customize the iOS Launch Screen assets

    master

    To change the image displayed during the app's launch on iOS, you can either replace the image files directly in the example/ruby/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    Using Xcode:

    1. Open the iOS project workspace using the command: open ios/Runner.xcworkspace.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  2. Configure 3D model assets

    master

    To render 3D models, you must include the Wavefront .obj files, their corresponding .mtl material files, and any associated texture images (e.g., .png) in your Flutter assets section.

    flutter:
      assets:
        - assets/cube/cube.obj
        - assets/cube/cube.mtl
        - assets/cube/flutter.png
  3. Customize iOS launch screen assets

    master

    To change the launch screen image for the iOS version of your Flutter application, you can use one of two methods:

    Method 1: Direct File Replacement

    Replace the existing image files directly within the example/bunny/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.

    Method 2: Using Xcode

    1. Open the iOS workspace by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Locate the LaunchImage asset set and drag and drop your desired images into it.
    open ios/Runner.xcworkspace
  4. Use the Cube widget to render 3D objects

    master

    Import package:flutter_cube/flutter_cube.dart and use the Cube widget. You can load 3D objects within the onSceneCreated callback by adding an Object to the scene.world using its asset file path.

    import 'package:flutter_cube/flutter_cube.dart';
    
    // ... inside your Widget build method
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: Center(
          child: Cube(
            onSceneCreated: (Scene scene) {
              scene.world.add(Object(fileName: 'assets/cube/cube.obj'));
            },
          ),
        ),
      );
    }
  5. Calculate a face normal vector

    master

    The normalVector function calculates the unit normal vector of a triangle defined by three points in 3D space. This is useful for lighting calculations.

    Signature

    Vector3 normalVector(Vector3 a, Vector3 b, Vector3 c)

    Vector3 a = Vector3(0, 0, 0);
    Vector3 b = Vector3(1, 0, 0);
    Vector3 c = Vector3(0, 1, 0);
    
    Vector3 normal = normalVector(a, b, c);
  6. Load textures for a Material using loadTexture

    master

    The loadTexture function attempts to resolve and load an image file specified in a Material's texture maps (mapKa or mapKd). It searches for the file by progressively stripping directory segments from the path and joining them with a basePath until the image is found.

    Parameters:

    • material: The Material object containing the texture path.
    • basePath: The base directory used to resolve the texture path.
    • isAsset: (Optional) Whether to load from assets (default true).

    Returns: A MapEntry<String, Image>? containing the resolved file path and the loaded Image object, or null if no texture could be loaded.

    MapEntry<String, Image>? textureEntry = await loadTexture(myMaterial, 'assets/textures/', isAsset: true);
    if (textureEntry != null) {
      String path = textureEntry.key;
      Image image = textureEntry.value;
    }
  7. Pack multiple mesh textures into a single atlas

    master

    The packingTexture function takes a list of Mesh objects and attempts to combine their individual textures into a single large texture atlas. This is an optimization technique to reduce draw calls.

    How it works

    1. It identifies unique textures across all meshes.
    2. It uses a rectangle packing algorithm to arrange these textures into a single large image.
    3. It updates each Mesh object's textureRect property to point to its new location within the combined atlas.
    4. It returns a single Image representing the complete atlas.

    Note: After calling this, you must use the updated textureRect on each mesh to sample the correct part of the new atlas.

    List<Mesh> meshes = await loadObj('model.obj', true);
    Image? atlas = await packingTexture(meshes);
    
    // The 'meshes' list now contains updated 'textureRect' values
    // pointing into the 'atlas' image.
  8. Convert between Vector3 and Color

    master

    These utility functions allow for easy conversion between vector_math's Vector3 (used for lighting calculations) and Flutter's Color class.

    • toColor(Vector3 v, [double opacity = 1.0]): Converts a Vector3 (where components are 0.0 to 1.0) to a Flutter Color.
    • fromColor(Color color): Converts a Flutter Color to a Vector3 (normalized 0.0 to 1.0).
    Vector3 colorVec = Vector3(1.0, 0.0, 0.0);
    Color flutterColor = toColor(colorVec);
    
    Color originalColor = Color(0xFF00FF00);
    Vector3 originalVec = fromColor(originalColor);
  9. Load materials from an .mtl file using loadMtl

    master

    Use loadMtl to parse a Material Library File (.mtl) and return a map of material names to Material objects. You can specify whether the file is located in the Flutter assets or as a local file using the isAsset flag.

    Parameters:

    • fileName: The path to the .mtl file.
    • isAsset: (Optional) Set to true to load from Flutter assets (default), or false to load from the local file system.
    Map<String, Material> materials = await loadMtl('assets/models/my_model.mtl', isAsset: true);