public Vector3 CalculateBrushOffsetUp() { if (!HasPreviewPrefab()) { return(Vector3.zero); } Bounds bounds = BoundsUtils.CalculateBounds(previewPrefab.prefabInstance.transform.gameObject); // the offset is in mouse wheel dimensions. we don't want the full offset // plates should have finer granularity than huge rocks float offsetReduction = bounds.size.y / 100f; // 1/100 is just arbitrary. let's see how that turns out during usage, might change later float offsetUp = previewPrefab.prefabSettings.brushOffsetUp * offsetReduction; return(previewPrefab.prefabInstance.transform.up * offsetUp); }
private PrefabTransform CreateAppliedTransform(PrefabSettings prefabSettings, Vector3 position, Vector3 normal) { /// /// Calculate position / rotation / scale /// // get new position Vector3 newPosition = position; // add offset of brush in up direction newPosition += CalculateBrushOffsetUp(); // add offset of prefab settings newPosition += prefabSettings.positionOffset; // auto physics height offset newPosition = ApplyAutoPhysicsHeightOffset(newPosition); Vector3 newLocalScale = prefabSettings.prefab.transform.localScale; // size // please note that the scale might be change later again (scale to brush size) // which should happen after the rotation if (prefabSettings.changeScale) { newLocalScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax); } // rotation Quaternion alignedRotation = Quaternion.identity; Quaternion objectRotation; if (this.editorTarget.brushSettings.alignToTerrain) { alignedRotation = Quaternion.FromToRotation(Vector3.up, normal); } if (prefabSettings.randomRotation) { objectRotation = prefabSettings.instanceRotation; } else { objectRotation = Quaternion.Euler(prefabSettings.rotationOffset); } // additionally consider brush rotation Quaternion brushRotation = Quaternion.Euler(0f, editorTarget.brushSettings.brushRotation, 0f); // combine terrain aligned rotation and object rotation Quaternion newRotation = alignedRotation * objectRotation * brushRotation; // scale to brush size // this uses world bounds and happens after the rotation if (editorTarget.brushSettings.distribution == BrushSettings.Distribution.Fluent) { GameObject prefab = prefabSettings.prefab; Quaternion prevRotation = prefab.transform.rotation; { // we need to rotate the gameobject now in order to calculate the world bounds prefab.transform.rotation = newRotation; float brushSize = editorTarget.brushSettings.brushSize; Bounds worldBounds = BoundsUtils.CalculateBounds(prefab); Vector3 prefabScale = prefab.transform.localScale; float scaleFactorX = brushSize / worldBounds.size.x; float scaleFactorY = brushSize / worldBounds.size.y; float scaleFactorZ = brushSize / worldBounds.size.z; float scaleFactorXYZ = Mathf.Min(scaleFactorX, scaleFactorY, scaleFactorZ); newLocalScale = prefabScale * scaleFactorXYZ; } prefab.transform.rotation = prevRotation; } PrefabTransform prefabTransform = new PrefabTransform(newPosition, newRotation, newLocalScale); return(prefabTransform); }