private MatrixObjectBoxPair CalculateMatrixObjectBoxPair(int brushElementIndex, ObjectSurfaceData objectSurfaceData) { // Store the needed data for easy access DecorPaintObjectPlacementBrushElement brushElement = _allValidBrushElements[brushElementIndex]; OrientedBox objectBox = new OrientedBox(_brushElementsPrefabOrientedBoxes[brushElementIndex]); // Establish the object's scale. Randomize the scale if necessary. Otherwise, just use the brush element's scale. Vector3 xyzObjectBoxScale = _brushElementsPrefabWorldScaleValues[brushElementIndex]; if (brushElement.ScaleRandomizationSettings.RandomizeScale) { // Generate a random scale factor and apply it to the current scale ObjectUniformScaleRandomizationSettings uniformScaleRandomizationSettings = brushElement.ScaleRandomizationSettings.UniformScaleRandomizationSettings; xyzObjectBoxScale *= UnityEngine.Random.Range(uniformScaleRandomizationSettings.MinScale, uniformScaleRandomizationSettings.MaxScale);; } else { xyzObjectBoxScale *= brushElement.Scale; } // Apply the scale that we have calculated objectBox.Scale = xyzObjectBoxScale; // Now we will calculate the rotation. First we will calculate a quaternion which allow us to take the // specified rotation offset into account. The quaternion rotates around the surface normal by an angle // of 'RotationOffset' degrees. Quaternion rotationOffset = brushElement.AlignToSurface ? Quaternion.AngleAxis(brushElement.RotationOffsetInDegrees, objectSurfaceData.SurfaceNormal) : Quaternion.identity; // If we need to align to stroke, we have some more work to do. Otherwise, we will just set the // rotation to be the same as the prefab's rotation, but offset by 'rotationOffset'. if (brushElement.AlignToStroke) { // First calculate the rotation without any offset. This is the rotation of the prefab plus the rotation which // must be applied for alignment. Quaternion rotationWithoutOffset = _rotationToApplyForStrokeAlignment * _elementToCurrentPrefabRotation[brushElement]; // The rotation of the box must be set to the rotation which we just calculated (which ensures proper alingment) plus // the rotation offset. objectBox.Rotation = rotationOffset * rotationWithoutOffset; // Store the rotation inside the dictionary if an entry doesn't already exist if (!_elementToNewPrefabRotation.ContainsKey(brushElement)) { _elementToNewPrefabRotation.Add(brushElement, rotationWithoutOffset); } } else { objectBox.Rotation = rotationOffset * brushElement.Prefab.UnityPrefab.transform.rotation; } // Adjust the rotation of the object so that its axis is aligned with the placement surface if necessary if (brushElement.AlignToSurface) { AdjustObjectBoxRotationOnSurface(objectBox, objectSurfaceData, brushElement); } // The final step is to rotate the object by a random amount around the placement surface if (brushElement.RotationRandomizationMode != BrushElementRotationRandomizationMode.None) { Vector3 rotationAxis = objectSurfaceData.SurfaceNormal; if (brushElement.RotationRandomizationMode == BrushElementRotationRandomizationMode.X) { rotationAxis = Vector3.right; } else if (brushElement.RotationRandomizationMode == BrushElementRotationRandomizationMode.Y) { rotationAxis = Vector3.up; } else if (brushElement.RotationRandomizationMode == BrushElementRotationRandomizationMode.Z) { rotationAxis = Vector3.forward; } if (!brushElement.AlignToStroke) { // When stroke alignment is not required, we will generate a random rotation angle and apply it // to the current box rotation. float randomRotationAngle = UnityEngine.Random.Range(0.0f, 360.0f); Quaternion additionalRotation = Quaternion.AngleAxis(randomRotationAngle, rotationAxis); objectBox.Rotation = additionalRotation * objectBox.Rotation; } else { // When both rotation randomization and stroke alingment are turned on, we will proudce a small // random rotation offset to randomize the alingmnet a little bit. float randomRotationAngle = UnityEngine.Random.Range(0.0f, 25.0f); Quaternion additionalRotation = Quaternion.AngleAxis(randomRotationAngle, rotationAxis); objectBox.Rotation = additionalRotation * objectBox.Rotation; } } // Place the object on the surface AdjustObjectBoxCenterToSitOnSurface(objectBox, objectSurfaceData, brushElement); // Construct the object matrix and return the object/marix pair TransformMatrix objectMatrix = new TransformMatrix(ObjectPositionCalculator.CalculateObjectHierarchyPosition(brushElement.Prefab, objectBox.Center, xyzObjectBoxScale, objectBox.Rotation), objectBox.Rotation, xyzObjectBoxScale); return(new MatrixObjectBoxPair(objectMatrix, objectBox)); }
public ObjectUniformScaleRandomizationSettingsView(ObjectUniformScaleRandomizationSettings settings) { _settings = settings; }