How to update geometry position in the scene after dragged using TransformControls

I have a scene in which there are multiple 3d-models which I can drag/scale/rotate using TransformControls. Now, I want to save the positions of the models after dragged when exported, but it’s not getting saved. The place where I insert the model for the first time, it holds that particular position when exported using GLTFExporter, even when dragged.

Here is what I am doing:

  • Open an empty scene, with grid, camera, light
  • Insert 3d-models into it at some positions
  • Drag the 3d-models using TransformControls
  • Export the scene using GLTFExporter
  • Import the exported-scene using GLTFLoader

Observations:

  • I see the assets in the same position where it was placed in the first place

Required Result:

  • The assets should be in its new position after dragged.

Here is the code snippet which is giving me the above-mentioned observation

onDocumentMouseDown(event) {
event.preventDefault()
let rect = this.renderer.domElement.getBoundingClientRect();
this.mouse.set(
  ( (event.clientX ) / rect.width ) * 2 - 1,
  - ( (event.clientY - rect.top )  / rect.height ) * 2 + 1
)
this.raycaster.setFromCamera(this.mouse, this.camera)
this.intersects = this.raycaster.intersectObjects(this.objects, true)
if (this.intersects.length > 0 && this.count < 2)  {
  this.intersect = this.intersects[0]
  this.loader.load(
    'http://localhost:3001/assets/bean_bag.obj',
    obj => {
      this.count += 1
      let mergedGeo = new THREE.BufferGeometry()
      let mergedMaterial, mergedMesh
      let geoArray = []
      this.object = obj
      this.object.traverse(child => {
        if (child instanceof THREE.Mesh) {
          child.material.map = this.texture
          let geometry = child.geometry
          geometry.applyMatrix(child.matrixWorld)
          child.updateMatrix()
          geoArray.push(geometry)
          mergedMaterial = child.material
        }
      })
      mergedGeo = BufferGeometryUtils.mergeBufferGeometries(
        geoArray,
        false
      )
      mergedMesh = new THREE.Mesh(mergedGeo, mergedMaterial)
      this.object = mergedMesh
      this.object.name = this.generateName(/*asset name*/ name)
      this.object.scale.set(2.54, 2.54, 2.54) // needs to fix scaling for assets
      this.object.position
        .copy(this.intersect.point)
      this.objects.push(this.object) // this is being used to attach transformcontrols on mosemove event
      this.scene.add(this.object)
      this.exportedScene.add(this.object.clone()) // this is the scene which gets exported
      this.animate()
    }
  )
},
exportScene() {
this.cloneSceneMeshes()
this.gltfExporter = new GLTFExporter()
this.gltfExporter.parse(this.exportedScene, result => {
  if (result instanceof ArrayBuffer) {
    this.saveArrayBuffer(result, 'scene.glb')
  } else {
    const scene_output = JSON.stringify(result, null, 2)
    console.log( scene_output );
    this.saveString(scene_output, 'scene.gltf')
  }
})
}
cloneSceneMeshes() {
if (this.exportScene) {
  this.exportedScene.background = new THREE.Color( 0xf0f0f0 );
  this.exportedScene.add(this.ambientLight.clone())
  this.exportedScene.add(this.camera.clone())
}

}

Is there a special reason for maintaining two different scenes? You have this.scene and this.exportedScene. This should not be necessary if you want to export your scene to glTF.

Anyway, the problem is you only transform the objects of your base scene but not the ones of the scene intended for exporting. If you clone a 3D object, it has an own transformation which is independent from its source object.

1 Like

is there a special reason for maintaining two different scenes? You have this.scene and this.exportedScene . This should not be necessary if you want to export your scene to glTF .

Yes, I think so. I don’t want to export the grid on which the template and assets are going to be placed - just the template and assets need to be exported. For that, I thought of creating another scene without the grid, not breaking the flow in whatsoever way. There might be a way to handle this gracefully with the same scene but this is currently of least priority. But thanks, for pointing it out! Otherwise, I would have forgotten.

Anyway, the problem is you only transform the objects of your base scene but not the ones of the scene intended for exporting. If you clone a 3D object, it has an own transformation which is independent from its source object.

Thanks, I will try this out and see if it helps. Seems like it should work - I will update the thread once I am done testing.

Thanks! :slight_smile: