Ejemplo n.º 1
0
    private bool PlaceObjects()
    {
        if (Event.current.type != EventType.KeyDown)
        {
            return(false);
        }

        Event.current.Use();

        if (_lastHitTangentSpace == null)
        {
            // No location to place something.
            // But it's handled.
            return(true);
        }

        if (Event.current.keyCode != KeyCode.Space)
        {
            // Currently only space is used, ignore the reset...
            // But it's handled.
            return(true);
        }

        foreach (PlacementLocation location in RandomLocations.Where(rl => rl.HitSurface))
        {
            // Skip when normal too much off.
            float angle          = Vector3.Angle(_lastHitTangentSpace.Up, location.Normal);
            float thresholdAngle = 45;

            if (angle > thresholdAngle)
            {
                // TOO Steep
                continue;
            }

            GameObject prefab = GetPrefab();
            Undo.RegisterCreatedObjectUndo(prefab, "Spawn Objects");
            prefab.name += $" ∠{angle}";
            prefab.transform.position = location.WorldPosition;
            prefab.transform.rotation = location.Rotation;

            if (Container)
            {
                prefab.transform.SetParent(Container.transform, true);
            }
        }

        GenerateRandomLocations(SpawnCount, true);

        return(true);
    }
Ejemplo n.º 2
0
    private void UpdateSceneUI()
    {
        if (Event.current.type != EventType.Repaint || _lastHitTangentSpace == null)
        {
            return;
        }

        Handles.zTest = CompareFunction.LessEqual;

        // Draw the current situation.
        _lastHitTangentSpace.DrawHandles();

        // The tangent plane.
        // Handles.color = new Color(0, 0, 0, .5f);
        // Handles.DrawSolidDisc(hit.point + hit.normal * .01f, hit.normal, Radius);
        // The ray plane.
        // Handles.color = new Color(0, 0, 0, .5f);
        // Handles.DrawSolidDisc(hit.point + _rayElevationHeight * hit.normal, hit.normal, Radius);

        DrawBrush(Color.blue, 6f, 256);

        foreach (PlacementLocation location in RandomLocations.Where(rl => rl.HitSurface))
        {
            // Skip when normal too much off.
            float      angle          = Vector3.Angle(_lastHitTangentSpace.Up, location.Normal);
            float      thresholdAngle = 30;
            GameObject activePrefab   = GetActivePrefab(location.PrefabIndex);

            if (activePrefab == null)
            {
                Color handleColor = GetAngleColor(angle, thresholdAngle);
                // Draw a dot where a placement will occur.
                Handles.color = handleColor;
                Handles.SphereHandleCap(-1, location.WorldPosition, Quaternion.identity, .1f, EventType.Repaint);
                // Draw the local normal
                Handles.color = Color.black;
                Handles.DrawAAPolyLine(5f, location.WorldPosition, location.WorldPosition + location.Normal);
            }
            else
            {
                if (angle > thresholdAngle)
                {
                    continue;
                }

                RenderModelAtLocation(activePrefab, location);
            }
        }
    }
Ejemplo n.º 3
0
    private void UpdatePlacementLocations()
    {
        foreach (PlacementLocation location in RandomLocations.ToArray())
        {
            // Scale the point in the unit-circle to a circle of specified radius.
            Vector2 localPoint   = location.UnitLocation * Radius;
            Ray     placementRay = _lastHitTangentSpace.GetTangentRay(localPoint, _rayElevationHeight);
            bool    validSurface = false;
            bool    hitSurface   = Physics.Raycast(placementRay, out RaycastHit placementHit);

            if (hitSurface)
            {
                GameObject surfaceObject = placementHit.transform.gameObject;
                int        surfaceLayer  = surfaceObject.layer;
                int        surfaceMask   = 1 << surfaceLayer;
                validSurface = (SurfaceLayers.value & surfaceMask) == surfaceMask;
            }

            if (validSurface)
            {
                // Align the object with the Normal vector of the local plane.
                Quaternion rotation = Quaternion.FromToRotation(Vector3.up, location.Normal);
                // Give it a random rotation around the Normal vector.
                rotation *= location.Orientation;                 // Quaternion.Euler(0, Random.value * 360, 0);

                location.HitSurface    = true;
                location.WorldPosition = placementHit.point;
                location.Normal        = placementHit.normal;
                location.Rotation      = rotation;
            }
            else
            {
                location.HitSurface = false;
#if DEBUG
                location.WorldPosition = Vector3.zero;
                location.Normal        = Vector3.zero;
#endif
            }
        }
    }