Flutter 3D Controller

repository·master·Indexed 41 days ago

https://github.com/m-r-davari/flutter_3d_controller

A Flutter package for rendering interactive 3D models in GLB, GLTF, and OBJ formats. It provides the Flutter3DViewer and ModelViewer widgets, along with the Flutter3DController for programmatic control over animations, textures, camera, and rotation. Built on Google's model-viewer engine, it supports AR configurations, custom lighting, and platform-specific optimizations for Android, iOS, Web, and macOS.

Tokens
5.5K
Snippets
17
Records
21
Agent score
52%

What's inside Flutter 3D Controller

  1. Understand the underlying rendering engine

    master
    This package utilizes Google's model-viewer as its core rendering engine. Because it relies on model-viewer, you may encounter rendering issues with certain specific models or textures. The project roadmap includes plans to update the core engine to improve support for a wider variety of 3D model types.
  2. Configure macOS for Flutter 3D Controller

    master

    macOS requires two specific configurations:

    1. App Sandbox: Enable Outgoing Connections (Client) in your Xcode project under Runner > Signing & Capabilities to allow model loading.
    2. Transparent Background: Add specific code to your AppDelegate to support transparent backgrounds in the viewer.
    // AppDelegate.swift
    import flutter_inappwebview_macos
    
    extension InAppWebView {
        @objc public override func viewDidMoveToWindow() {
            super.viewDidMoveToWindow()
            
            if window != nil {
                self.setValue(false, forKey: "opaque")
                self.setValue(false, forKey: "drawsBackground")
                self.layer?.backgroundColor = NSColor.clear.cgColor
            }
        }
    }
  3. Configure Web for Flutter 3D Controller

    master

    For Web support, modify the <head> tag in your web/index.html to include the required model_viewer.min.js script.

    <head>
      <!-- Other stuff -->
      <script type="module" src="./assets/packages/flutter_3d_controller/assets/model_viewer.min.js" defer></script>
    </head>
  4. Configure Android for Flutter 3D Controller

    master

    For Android support, you must update your AndroidManifest.xml and build.gradle files.

    1. Permissions & Network: Add INTERNET permission and enable usesCleartextTraffic in android/app/src/main/AndroidManifest.xml to allow loading models from URLs.
    2. Minimum SDK: Set minSdkVersion to 21 in android/app/build.gradle.
    <!-- AndroidManifest.xml -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        ...
        android:usesCleartextTraffic="true">
    // app/build.gradle
    defDefaultConfig {
        minSdkVersion 21
    }
  5. 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/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    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. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  6. Configure ModelViewer loading and reveal behavior

    master

    You can control how and when a 3D model is loaded and displayed to optimize performance and user experience.

    • loading: Determines when the model is preloaded.
      • Loading.auto: Loads when near the viewport (if reveal is auto) or when interacted with (if reveal is interaction).
      • Loading.lazy: Similar to auto.
      • Loading.eager: Loads the model immediately.
    • reveal: Determines when the model becomes visible.
      • Reveal.auto: Reveals as soon as loading and rendering are complete.
      • Reveal.interaction: Waits until the user interacts with the poster image.
      • Reveal.manual: Remains hidden until dismissPoster() is called (via JS/Controller).
    ModelViewer(
      src: 'assets/model.glb',
      loading: Loading.eager,
      reveal: Reveal.interaction,
      poster: 'assets/poster.png',
    );
  7. Use the Flutter3DViewer widget for 3D model rendering

    master

    The Flutter3DViewer widget is the primary entry point for rendering 3D models in your Flutter application. It supports both standard 3D models (like .glb and .gltf) and .obj models via specialized constructors.

    Standard 3D Models (.glb, .gltf)

    Use the default constructor to load standard web-optimized 3D models. You can provide a Flutter3DController to programmatically control animations, camera, and variants.

    OBJ Models

    Use the Flutter3DViewer.obj constructor specifically for .obj files. This constructor allows you to define initial camera positioning and scaling parameters.

    Key Features

    • Source Support: Load models via asset addresses, URLs, or local file paths.
    • Gesture Interceptor: Includes an activeGestureInterceptor (enabled by default) to prevent gesture conflicts on iOS and certain Android devices.
    • Lifecycle Callbacks: Monitor loading progress, successful loads, and errors via onProgress, onLoad, and onError.
    // Loading a standard GLB model
    Flutter3DViewer(
      src: 'assets/models/my_model.glb',
      onProgress: (progress) => print('Loading: $progress'),
      onLoad: (address) => print('Loaded: $address'),
      onError: (error) => print('Error: $error'),
    );
    
    // Loading an OBJ model with specific camera settings
    Flutter3DViewer.obj(
      src: 'assets/models/my_model.obj',
      scale: 2.0,
      cameraX: 0.0,
      cameraY: 5.0,
      cameraZ: 15.0,
    );
  8. Troubleshoot 3D model loading issues

    master

    If your 3D model fails to load, follow these troubleshooting steps:

    1. Verify Model and Path: Compare your implementation with the provided examples. If the examples work but your model does not, the issue is likely with your specific model file or the file path provided.
    2. Check URL/CORS Restrictions: If loading a model from a URL, ensure the hosting server sends appropriate CORS (Cross-Origin Resource Sharing) response headers. Without these headers, the viewer will be blocked from loading the file.
    3. Animation Retrieval: If the animation list is empty or cannot be retrieved, check your model's animation names for special characters that might cause JSON encoding errors.
  9. Use Flutter3DController to control animations and rotation

    master

    The Flutter3DController allows you to programmatically control the 3D model's state, including animations, textures, camera, and rotation.

    Animation Control

    • playAnimation({String? animationName, int loopCount = 0}): Plays an animation. If animationName is null, plays the first available. loopCount determines repetitions.
    • pauseAnimation(): Pauses at the current frame.
    • resetAnimation(): Resets to the first frame.
    • stopAnimation(): Stops the animation.
    • getAvailableAnimations(): Returns a list of available animation names.

    Rotation Control

    • startRotation({double rotationSpeed = 10}): Starts continuous rotation at the specified speed (deg/s).
    • pauseRotation(): Pauses rotation at the current orientation.
    • stopRotation(): Stops rotation and resets to initial position.

    Texture and Camera Control

    • setTexture({required String textureName}): Switches the model texture.
    • getAvailableTextures(): Returns a list of available texture names.
    • setCameraTarget(double x, double y, double z): Sets the camera focus point.
    • resetCameraTarget(): Resets to default target.
    • setCameraOrbit(double x, double y, double z): Sets the camera orbit.
    • resetCameraOrbit(): Resets to default orbit.
    Flutter3DController controller = Flutter3DController();
    
    // Listen to loading
    controller.onModelLoaded.addListener(() {
      debugPrint('model is loaded : ${controller.onModelLoaded.value}');
    });
    
    // Animation examples
    controller.playAnimation(animationName: 'Walk', loopCount: 2);
    controller.pauseAnimation();
    
    // Rotation examples
    controller.startRotation(rotationSpeed: 30);
    controller.stopRotation();
    
    // Texture examples
    await controller.setTexture(textureName: 'Gold');
  10. Load OBJ models with Flutter3DViewer.obj

    master

    Use the Flutter3DViewer.obj constructor to render .obj files. This method includes specific properties for scale and initial camera positioning.

    Key Properties:

    • src: Path to the .obj asset or URL.
    • scale: Initial scale of the model.
    • cameraX, cameraY, cameraZ: Initial camera position.
    • onProgress, onLoad, onError: Standard loading callbacks.
    Flutter3DViewer.obj(
        src: 'assets/flutter_dash.obj',
        scale: 5,
        cameraX: 0,
        cameraY: 0,
        cameraZ: 10,
        onProgress: (double progressValue) {
          debugPrint('model loading progress : $progressValue');
        },
        onLoad: (String modelAddress) {
          debugPrint('model loaded : $modelAddress');
        },
        onError: (String error) {
          debugPrint('model failed to load : $error');
        },
    )