Skip to content

nirvik-d/Import-glTF-models

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Import glTF Models

A web application that demonstrates how to import and place glTF 3D models on a map using ArcGIS JavaScript API.

Features

  • 3D Model Import: Supports importing glTF models (Shiba and Tower)
  • Interactive Placement: Place models on the map using mouse clicks
  • Real-time Updates: Automatic UI updates based on model selection
  • Multiple Model Support: Choose between different 3D models
  • Ground Elevation: Models are automatically placed on ground level

Screenshot

  1. The main application image

Prerequisites

  • Node.js
  • Vite

Project Setup

Initialize Project

npm create vite@latest

Follow the instructions on screen to initialize the project.

Install Dependencies

npm install @arcgis/map-components

Code Structure

HTML Structure

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <title>Import glTF models</title>
  </head>
  <body>
    <arcgis-scene item-id="414a28cfca7a471180e8e952cf14c60f">
      <arcgis-zoom position="top-left"></arcgis-zoom>
      <arcgis-navigation-toggle position="top-left"></arcgis-navigation-toggle>
      <arcgis-compass position="top-left"></arcgis-compass>
      <div id="paneDiv" class="esri-widget">
        <p>Select a symbol and place it in the scene:</p>
        <button id="shiba" class="esri-button">Shiba</button><br />
        <button id="tower" class="esri-button">Tower</button>
      </div>
    </arcgis-scene>
    <script type="module" src="./src/main.ts"></script>
  </body>
</html>

CSS Structure

@import "https://js.arcgis.com/calcite-components/3.2.1/calcite.css";
@import "https://js.arcgis.com/4.32/esri/themes/light/main.css";
@import "https://js.arcgis.com/4.32/map-components/main.css";

html,
body {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

#paneDiv {
  padding: 10px;
  max-width: 200px;
  background-color: rgba(255, 255, 255, 0.8);
  font-size: 1.1em;
}

TypeScript Structure

  1. Import the required modules
import "./style.css";

import "@arcgis/map-components/components/arcgis-scene";
import "@arcgis/map-components/components/arcgis-zoom";
import "@arcgis/map-components/components/arcgis-navigation-toggle";
import "@arcgis/map-components/components/arcgis-compass";

import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer";
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel";
import SceneView from "@arcgis/core/views/SceneView";
  1. Get the scene view
const webScene: HTMLArcgisSceneElement | null = document.querySelector("arcgis-scene");
if (!webScene) {
  throw new Error("Scene element not found");
}

await webScene.viewOnReady();

// Create the SceneView and attach it to the container
const view: SceneView | null = webScene.view;
if (!view) {
  throw new Error("View not found");
}
  1. Create a GraphicsLayer, get the burrons and create a sketch view model
// Create a GraphicsLayer for 3D models with ground elevation
const graphicsLayer: GraphicsLayer | null = new GraphicsLayer({
  elevationInfo: { mode: "on-the-ground" }, // Models will be placed on ground level
});
view.map?.add(graphicsLayer); // Add the graphics layer to the map

// Get UI elements for model selection
const shibaButton: HTMLButtonElement | null = document.querySelector("#shiba");
if (!shibaButton) {
  throw new Error("Shiba button not found");
}
const towerButton: HTMLButtonElement | null = document.querySelector("#tower");
if (!towerButton) {
  throw new Error("Tower button not found");
}

// Create SketchViewModel for placing 3D models
const model = new SketchViewModel({
  layer: graphicsLayer,
  view: view,
});
  1. Handle model placement
shibaButton.addEventListener("click", () => {
  // Configure the model symbol for Shiba
  model.pointSymbol = {
    type: "point-3d",
    symbolLayers: [
      {
        type: "object",
        resource: {
          href: "./shiba.glb", // Path to Shiba model
        },
      },
    ],
  };
  // Start model placement mode
  model.create("point");
  // Reset button states
  deactivateButton();
  // Highlight the selected button
  shibaButton.classList.add("esri-button-secondary");
});

// Handle Tower model placement
towerButton.addEventListener("click", () => {
  // Configure the model symbol for Tower
  model.pointSymbol = {
    type: "point-3d",
    symbolLayers: [
      {
        type: "object",
        resource: {
          href: "./tower.glb", // Path to Tower model
        },
      },
    ],
  };
  // Reset button states
  deactivateButton();
  // Start model placement mode
  model.create("point");
  // Highlight the selected button
  towerButton.classList.add("esri-button-secondary");
});
  1. Listen for model creation events
// Listen for model creation events
model.on("create", (event) => {
  if (event.state === "complete") {
    // Update the model with the created graphic
    model.update(event.graphic);
    // Reset button states
    deactivateButton();
  }
});
  1. Add a function to reset button states
function deactivateButton() {
  // Get all buttons with the esri-button class
  const elements = Array.prototype.slice.call(
    document.getElementsByClassName("esri-button")
  );
  // Remove the secondary button class from all buttons
  elements.forEach((element) => {
    element.classList.remove("esri-button-secondary");
  });
}
  1. Add the UI element to the scene view
view.ui.add("paneDiv", "top-right");

Running the Application

  1. For development, run:
npm run dev

The application can then be run on https://localhost:5173

  1. For production, run:
npm run build
npm run preview

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published