예제 #1
0
        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));
        }
예제 #2
0
 public ObjectUniformScaleRandomizationSettingsView(ObjectUniformScaleRandomizationSettings settings)
 {
     _settings = settings;
 }