void DrawBoxTransformationHandles(DecalProjector decalProjector) { using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { Vector3 centerStart = decalProjector.pivot; boxHandle.center = centerStart; boxHandle.size = decalProjector.size; Vector3 boundsSizePreviousOS = boxHandle.size; Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center; EditorGUI.BeginChangeCheck(); boxHandle.DrawHandle(); if (EditorGUI.EndChangeCheck()) { // Adjust decal transform if handle changed. Undo.RecordObject(decalProjector, "Decal Projector Change"); decalProjector.size = boxHandle.size; decalProjector.pivot += boxHandle.center - centerStart; Vector3 boundsSizeCurrentOS = boxHandle.size; Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; if (editMode == k_EditShapePreservingUV) { // Treat decal projector bounds as a crop tool, rather than a scale tool. // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds. Vector2 uvScale = decalProjector.uvScale; uvScale.x *= Mathf.Max(1e-5f, boundsSizeCurrentOS.x) / Mathf.Max(1e-5f, boundsSizePreviousOS.x); uvScale.y *= Mathf.Max(1e-5f, boundsSizeCurrentOS.y) / Mathf.Max(1e-5f, boundsSizePreviousOS.y); decalProjector.uvScale = uvScale; Vector2 uvBias = decalProjector.uvBias; uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(1e-5f, boundsSizeCurrentOS.x) * decalProjector.uvScale.x; uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(1e-5f, boundsSizeCurrentOS.y) * decalProjector.uvScale.y; decalProjector.uvBias = uvBias; } if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } // Smoothly update the decal image projected DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } } }
void DrawHandles() { //Note: each target need to be handled individually to allow multi edition DecalProjector decalProjector = target as DecalProjector; if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV) { using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { bool needToRefreshDecalProjector = false; handle.center = decalProjector.offset; handle.size = decalProjector.size; Vector3 boundsSizePreviousOS = handle.size; Vector3 boundsMinPreviousOS = handle.size * -0.5f + handle.center; EditorGUI.BeginChangeCheck(); handle.DrawHandle(); if (EditorGUI.EndChangeCheck()) { needToRefreshDecalProjector = true; // Adjust decal transform if handle changed. Undo.RecordObject(decalProjector, "Decal Projector Change"); decalProjector.size = handle.size; decalProjector.offset = handle.center; Vector3 boundsSizeCurrentOS = handle.size; Vector3 boundsMinCurrentOS = handle.size * -0.5f + handle.center; if (editMode == k_EditShapePreservingUV) { // Treat decal projector bounds as a crop tool, rather than a scale tool. // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds. Vector2 uvScale = decalProjector.uvScale; uvScale.x *= Mathf.Max(1e-5f, boundsSizeCurrentOS.x) / Mathf.Max(1e-5f, boundsSizePreviousOS.x); uvScale.y *= Mathf.Max(1e-5f, boundsSizeCurrentOS.y) / Mathf.Max(1e-5f, boundsSizePreviousOS.y); decalProjector.uvScale = uvScale; Vector2 uvBias = decalProjector.uvBias; uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(1e-5f, boundsSizeCurrentOS.x) * decalProjector.uvScale.x; uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(1e-5f, boundsSizeCurrentOS.y) * decalProjector.uvScale.y; decalProjector.uvBias = uvBias; } if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } } // Automatically recenter our transform component if necessary. // In order to correctly handle world-space snapping, we only perform this recentering when the user is no longer interacting with the gizmo. if ((GUIUtility.hotControl == 0) && (decalProjector.offset != Vector3.zero)) { needToRefreshDecalProjector = true; // Both the DecalProjectorComponent, and the transform will be modified. // The undo system will automatically group all RecordObject() calls here into a single action. Undo.RecordObject(decalProjector.transform, "Decal Projector Change"); // Re-center the transform to the center of the decal projector bounds, // while maintaining the world-space coordinates of the decal projector boundings vertices. // Center of the decal projector is not the same of the HierarchicalBox as we want it to be on the z face as lights decalProjector.transform.Translate(decalProjector.offset + new Vector3(0f, 0f, handle.size.z * -0.5f), Space.Self); decalProjector.offset = new Vector3(0f, 0f, handle.size.z * 0.5f); if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } } if (needToRefreshDecalProjector) { // Smoothly update the decal image projected DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } } } //[TODO: add editable pivot. Uncomment this when ready] //else if (editMode == k_EditUV) //{ // //here should be handles code to manipulate the pivot without changing the UV //} }
void DrawBoxTransformationHandles(DecalProjector decalProjector) { Vector3 scale = decalProjector.effectiveScale; using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, scale))) { Vector3 centerStart = decalProjector.pivot; boxHandle.center = centerStart; boxHandle.size = decalProjector.size; Vector3 boundsSizePreviousOS = boxHandle.size; Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center; EditorGUI.BeginChangeCheck(); boxHandle.DrawHandle(); if (EditorGUI.EndChangeCheck()) { // Adjust decal transform if handle changed. Undo.RecordObject(decalProjector, "Decal Projector Change"); bool xChangeIsValid = scale.x != 0f; bool yChangeIsValid = scale.y != 0f; bool zChangeIsValid = scale.z != 0f; // Preserve serialized state for axes with scale 0. decalProjector.size = new Vector3( xChangeIsValid ? boxHandle.size.x : decalProjector.size.x, yChangeIsValid ? boxHandle.size.y : decalProjector.size.y, zChangeIsValid ? boxHandle.size.z : decalProjector.size.z); decalProjector.pivot = new Vector3( xChangeIsValid ? boxHandle.center.x : decalProjector.pivot.x, yChangeIsValid ? boxHandle.center.y : decalProjector.pivot.y, zChangeIsValid ? boxHandle.center.z : decalProjector.pivot.z); Vector3 boundsSizeCurrentOS = boxHandle.size; Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; if (editMode == k_EditShapePreservingUV) { // Treat decal projector bounds as a crop tool, rather than a scale tool. // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds. // Preserve serialized state for axes with scale 0. Vector2 uvScale = decalProjector.uvScale; Vector2 uvBias = decalProjector.uvBias; if (xChangeIsValid) { uvScale.x *= Mathf.Max(k_LimitInv, boundsSizeCurrentOS.x) / Mathf.Max(k_LimitInv, boundsSizePreviousOS.x); uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(k_LimitInv, boundsSizeCurrentOS.x) * uvScale.x; } if (yChangeIsValid) { uvScale.y *= Mathf.Max(k_LimitInv, boundsSizeCurrentOS.y) / Mathf.Max(k_LimitInv, boundsSizePreviousOS.y); uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(k_LimitInv, boundsSizeCurrentOS.y) * uvScale.y; } decalProjector.uvScale = uvScale; decalProjector.uvBias = uvBias; } if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } // Smoothly update the decal image projected DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } } }