trois icon indicating copy to clipboard operation
trois copied to clipboard

TransformControls directive

Open SaFrMo opened this issue 3 years ago • 1 comments

One of the most time-consuming parts of creating a new scene from scratch is placing items in the scene, so I'd love to add in an optional directive (v-transform-control or similar) to allow easy placement, rotation, scaling, and copying items directly from the scene using TransformControls. I'll take a look at this when I have some more time - let me know if there are any other features you'd like to see!

SaFrMo avatar May 13 '21 19:05 SaFrMo

I was looking around for transformcontrols and found none that I could see. So I work on it and It took a while as there no select object add but mesh to move around the transform control handler. Well it can be convert to other format. Had to dig into the code to see how the component work in troisjs.

Added way to search using the scene uuid search and assign the transform control. It a lot testing to see if the script worked.

<script setup>
import { TransformControls } from 'three/examples/jsm/controls/TransformControls';
import {RendererInjectionKey, SceneInjectionKey, Mesh } from 'troisjs';
import { inject, onMounted, onUnmounted, ref, watch } from 'vue';

const props = defineProps({
  selectObjectID:String
})
const emit = defineEmits(['updateTransform']);
const renderer = inject(RendererInjectionKey);
const scene = inject(SceneInjectionKey);

//watch props changes params
watch(props,()=>{
  if(props.selectObjectID){
    let obj3d = scene.getObjectByProperty('uuid',props.selectObjectID)
    if(obj3d){
      transControls.attach(obj3d);
    }else{
      transControls.detach();
    }
  }
})

const transformControls = ref();
const refBox = ref();
let transControls;

function detectTransformHandle ( event ) {
  //console.log(event);
  //console.log(renderer.three.cameraCtrl)//okay
  renderer.three.cameraCtrl.enabled = !event.value;
  if(event.value==false){
    emit('updateTransform',transformControls.value.mode)
  }
}

//does not work as renderer is not setup yet
onMounted(() => {
  transControls = new TransformControls(renderer.three.camera, renderer.three.renderer.domElement)
  transformControls.value = transControls;
  transformControls.value.addEventListener('dragging-changed', detectTransformHandle);
  transControls.attach( refBox.value.mesh );
  scene.add(transControls)
  //scene.add(transformControls.value) //nope, error proxy
  window.addEventListener( 'keydown', controlTransform);
})

onUnmounted(() =>{
  transControls.detach();
  scene.remove(transControls)
  transformControls.value.removeEventListener( 'keydown', detectTransformHandle);
  window.removeEventListener( 'keydown', controlTransform);
});

function controlTransform(e){
  console.log(e.code)
  switch ( e.code ) {
    case 'KeyQ': // 
      transformControls.value.setSpace( transformControls.value.space === 'local' ? 'world' : 'local' );
      break;
    case 'KeyW': // W
      transformControls.value.setMode( 'translate' );
      break;
    case 'KeyE': // E
      transformControls.value.setMode( 'rotate' );
      break;
    case 'KeyR': // R
      transformControls.value.setMode( 'scale' );
      break;
    case 'NumpadSubtract': // 
      transformControls.value.setSize( Math.max( transformControls.value.size - 0.1, 0.1 ) );
      break;
    case 'NumpadAdd': // 
      transformControls.value.setSize( transformControls.value.size + 0.1 );
      break;
    case 'Space': // 
      transformControls.value.enabled = ! transformControls.value.enabled;
      break;
    case 'Escape': // Esc
      transformControls.value.reset();
      break;
  }
}
</script>
<template>
  <Mesh ref="refBox"/>    
</template>

Example.

const renderer = ref();
function updateTransform(mode){
//let obj3d = renderer.value.scene.getObjectByProperty('uuid',selectObjectUUID.value)
if(mode == "translate"){//position
}
if(mode == "rotate"){
}
if(mode == "scale"){
}
}
<EntityTransformControl :selectObjectID="selectObjectUUID" @update-transform="updateTransform"/>

Added the event for transformcontrol event for object update.

Lightnet avatar Mar 23 '22 01:03 Lightnet