< Summary

Class:VoxelController
Assembly:BuilderInWorld
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/States/EditorMode/Voxels/VoxelController.cs
Covered lines:1
Uncovered lines:150
Coverable lines:151
Total lines:317
Line coverage:0.6% (1 of 151)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
VoxelController()0%110100%
Start()0%2100%
OnDestroy()0%2100%
Update()0%72800%
SetSceneToEdit(...)0%2100%
SetEditObjectLikeVoxel()0%72800%
SetEditionGO(...)0%2100%
IsActive()0%2100%
SetActiveMode(...)0%2100%
EndMultiVoxelSelection()0%12300%
FillVoxels(...)0%2101400%
ExistVoxelAtPosition(...)0%12300%
CreateVoxel(...)0%6200%
MouseUp(...)0%90900%
MouseDown(...)0%20400%
SetVoxelSelected(...)0%2100%
ConverPositionToVoxelPosition(...)0%2100%
IsVoxelAtValidPoint(...)0%42600%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/States/EditorMode/Voxels/VoxelController.cs

#LineLine coverage
 1using System;
 2using DCL.Configuration;
 3using DCL.Controllers;
 4using DCL.Models;
 5using System.Collections;
 6using System.Collections.Generic;
 7using DCL.Camera;
 8using UnityEngine;
 9
 10public class VoxelController : MonoBehaviour
 11{
 12    [Header("References")]
 13    public VoxelPrefab voxelPrefab;
 14
 15    public BuilderInWorldController buildModeController;
 16    public BIWOutlinerController outlinerController;
 17    public BuilderInWorldEntityHandler builderInWorldEntityHandler;
 18    public FreeCameraMovement freeCameraMovement;
 19    public ActionController actionController;
 20
 21    public LayerMask groundLayer;
 22
 23    DCLBuilderInWorldEntity lastVoxelCreated;
 24
 25    GameObject editionGO;
 26    bool mousePressed = false, isVoxelModelActivated = false, isCreatingMultipleVoxels = false;
 27    Vector3Int lastVoxelPositionPressed;
 28    Vector3 lastMousePosition;
 19829    Dictionary<Vector3Int, VoxelPrefab> createdVoxels = new Dictionary<Vector3Int, VoxelPrefab>();
 30    ParcelScene currentScene;
 31
 32    const float RAYCAST_MAX_DISTANCE = 10000f;
 33    const float VOXEL_BOUND_ERROR = 0.05f;
 34
 35    private void Start()
 36    {
 037        BuilderInWorldInputWrapper.OnMouseDown += MouseDown;
 038        BuilderInWorldInputWrapper.OnMouseUp += MouseUp;
 039    }
 40
 41    private void OnDestroy()
 42    {
 043        BuilderInWorldInputWrapper.OnMouseDown -= MouseDown;
 044        BuilderInWorldInputWrapper.OnMouseUp -= MouseUp;
 045    }
 46
 47    private void Update()
 48    {
 049        if (!mousePressed || !isVoxelModelActivated || !isCreatingMultipleVoxels)
 050            return;
 51
 052        Vector3Int currentPosition = Vector3Int.zero;
 053        VoxelEntityHit voxelHit = buildModeController.GetCloserUnselectedVoxelEntityOnPointer();
 54
 055        if (voxelHit != null && voxelHit.entityHitted.tag == BuilderInWorldSettings.VOXEL_TAG && !voxelHit.entityHitted.
 56        {
 057            Vector3Int position = ConverPositionToVoxelPosition(voxelHit.entityHitted.rootEntity.gameObject.transform.po
 058            position += voxelHit.hitVector;
 59
 060            currentPosition = position;
 061            FillVoxels(lastVoxelPositionPressed, currentPosition);
 062        }
 63        else
 64        {
 65            RaycastHit hit;
 066            UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 67
 068            if (Physics.Raycast(ray, out hit, RAYCAST_MAX_DISTANCE, groundLayer))
 69            {
 070                currentPosition = ConverPositionToVoxelPosition(hit.point);
 071                FillVoxels(lastVoxelPositionPressed, currentPosition);
 72            }
 73        }
 074    }
 75
 076    public void SetSceneToEdit(ParcelScene scene) { currentScene = scene; }
 77
 78    public void SetEditObjectLikeVoxel()
 79    {
 080        if (mousePressed || !isVoxelModelActivated)
 081            return;
 82
 083        VoxelEntityHit voxelHit = buildModeController.GetCloserUnselectedVoxelEntityOnPointer();
 84
 085        if (voxelHit != null && voxelHit.entityHitted.IsSelected)
 086            return;
 87
 088        if (voxelHit != null && voxelHit.entityHitted.tag == BuilderInWorldSettings.VOXEL_TAG)
 89        {
 090            Vector3 position = ConverPositionToVoxelPosition(voxelHit.entityHitted.rootEntity.gameObject.transform.posit
 091            position += voxelHit.hitVector;
 092            editionGO.transform.position = position;
 093        }
 94        else
 95        {
 96            RaycastHit hit;
 097            UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 98
 099            if (Physics.Raycast(ray, out hit, RAYCAST_MAX_DISTANCE, groundLayer))
 100            {
 0101                Vector3 position = hit.point;
 0102                editionGO.transform.position = ConverPositionToVoxelPosition(hit.point);
 103            }
 104        }
 0105    }
 106
 0107    public void SetEditionGO(GameObject editionGO) { this.editionGO = editionGO; }
 108
 0109    public bool IsActive() { return isVoxelModelActivated; }
 110
 0111    public void SetActiveMode(bool isActive) { isVoxelModelActivated = isActive; }
 112
 113    public void EndMultiVoxelSelection()
 114    {
 0115        List<DCLBuilderInWorldEntity> voxelEntities = builderInWorldEntityHandler.GetAllVoxelsEntities();
 116
 0117        foreach (DCLBuilderInWorldEntity voxelEntity in voxelEntities)
 118        {
 0119            if (BuilderInWorldUtils.IsWithInSelectionBounds(voxelEntity.gameObject.transform, lastMousePosition, Input.m
 120            {
 0121                builderInWorldEntityHandler.SelectEntity(voxelEntity);
 122            }
 123        }
 124
 0125        outlinerController.SetOutlineCheckActive(true);
 0126        outlinerController.CancelAllOutlines();
 0127    }
 128
 129    void FillVoxels(Vector3Int firstPosition, Vector3Int lastPosition)
 130    {
 0131        int xDifference = Mathf.Abs(firstPosition.x - lastPosition.x);
 0132        int yDifference = Mathf.Abs(firstPosition.y - lastPosition.y);
 0133        int zDifference = Mathf.Abs(firstPosition.z - lastPosition.z);
 134
 0135        List<Vector3Int> mustContainVoxelList = new List<Vector3Int>();
 0136        List<DCLBuilderInWorldEntity> voxelEntities = builderInWorldEntityHandler.GetAllVoxelsEntities();
 0137        List<DCLBuilderInWorldEntity> allEntities = builderInWorldEntityHandler.GetAllEntitiesFromCurrentScene();
 138
 0139        for (int x = 0; x <= xDifference; x++)
 140        {
 0141            int contX = x;
 0142            if (firstPosition.x > lastPosition.x)
 0143                contX = -contX;
 144
 0145            for (int y = 0; y <= yDifference; y++)
 146            {
 0147                int contY = y;
 0148                if (firstPosition.y > lastPosition.y)
 0149                    contY = -contY;
 150
 0151                for (int z = 0; z <= zDifference; z++)
 152                {
 0153                    int contZ = z;
 0154                    if (firstPosition.z > lastPosition.z)
 0155                        contZ = -contZ;
 156
 0157                    Vector3Int positionOfVoxel = new Vector3Int(firstPosition.x + contX, firstPosition.y + contY, firstP
 0158                    if (positionOfVoxel == firstPosition)
 159                        continue;
 0160                    if (ExistVoxelAtPosition(positionOfVoxel, voxelEntities))
 161                        continue;
 0162                    CreateVoxel(positionOfVoxel);
 0163                    mustContainVoxelList.Add(positionOfVoxel);
 164                }
 165            }
 166        }
 167
 168
 0169        List<Vector3Int> voxelToRemove = new List<Vector3Int>();
 0170        foreach (Vector3Int position in createdVoxels.Keys)
 171        {
 0172            if (!mustContainVoxelList.Contains(position))
 0173                voxelToRemove.Add(position);
 174        }
 175
 0176        foreach (Vector3Int vector in voxelToRemove)
 177        {
 0178            Destroy(createdVoxels[vector].gameObject);
 0179            createdVoxels.Remove(vector);
 180        }
 181
 0182        foreach (VoxelPrefab keyValuePair in createdVoxels.Values)
 183        {
 0184            if (IsVoxelAtValidPoint(keyValuePair, allEntities))
 0185                keyValuePair.SetAvailability(true);
 186            else
 0187                keyValuePair.SetAvailability(false);
 188        }
 0189    }
 190
 191    bool ExistVoxelAtPosition(Vector3Int position, List<DCLBuilderInWorldEntity> voxelEntities)
 192    {
 0193        foreach (DCLBuilderInWorldEntity voxelEntity in voxelEntities)
 194        {
 0195            if (position == ConverPositionToVoxelPosition(voxelEntity.transform.position))
 0196                return true;
 197        }
 198
 0199        return false;
 0200    }
 201
 202    VoxelPrefab CreateVoxel(Vector3Int position)
 203    {
 0204        if (!createdVoxels.ContainsKey(position))
 205        {
 0206            VoxelPrefab go = Instantiate(voxelPrefab.gameObject, position, lastVoxelCreated.rootEntity.gameObject.transf
 0207            createdVoxels.Add(position, go);
 0208            return go;
 209        }
 210
 0211        return null;
 212    }
 213
 214    private void MouseUp(int buttonID, Vector3 position)
 215    {
 0216        if (!mousePressed || buttonID != 0)
 0217            return;
 218
 0219        if (isCreatingMultipleVoxels)
 220        {
 0221            lastVoxelCreated.transform.SetParent(null);
 0222            bool canVoxelsBeCreated = true;
 223
 0224            foreach (VoxelPrefab voxel in createdVoxels.Values)
 225            {
 0226                if (!voxel.IsAvailable())
 227                {
 0228                    canVoxelsBeCreated = false;
 0229                    break;
 230                }
 231            }
 232
 0233            BuildInWorldCompleteAction buildAction = new BuildInWorldCompleteAction();
 0234            buildAction.actionType = BuildInWorldCompleteAction.ActionType.CREATE;
 235
 0236            List<BuilderInWorldEntityAction> entityActionList = new List<BuilderInWorldEntityAction>();
 237
 0238            foreach (Vector3Int voxelPosition in createdVoxels.Keys)
 239            {
 0240                if (canVoxelsBeCreated)
 241                {
 0242                    IDCLEntity entity = builderInWorldEntityHandler.DuplicateEntity(lastVoxelCreated).rootEntity;
 0243                    entity.gameObject.tag = BuilderInWorldSettings.VOXEL_TAG;
 0244                    entity.gameObject.transform.position = voxelPosition;
 245
 0246                    BuilderInWorldEntityAction builderInWorldEntityAction = new BuilderInWorldEntityAction(entity, entit
 0247                    entityActionList.Add(builderInWorldEntityAction);
 248                }
 249
 0250                Destroy(createdVoxels[voxelPosition].gameObject);
 251            }
 252
 0253            if (!canVoxelsBeCreated)
 254            {
 0255                builderInWorldEntityHandler.DeleteEntity(lastVoxelCreated);
 0256            }
 257            else
 258            {
 0259                buildAction.CreateActionType(entityActionList, BuildInWorldCompleteAction.ActionType.CREATE);
 0260                actionController.AddAction(buildAction);
 261            }
 262
 0263            createdVoxels.Clear();
 0264            builderInWorldEntityHandler.DeselectEntities();
 265
 0266            lastVoxelCreated = null;
 0267            isCreatingMultipleVoxels = false;
 268
 0269            mousePressed = false;
 0270            freeCameraMovement.SetCameraCanMove(true);
 271        }
 0272    }
 273
 274    void MouseDown(int buttonID, Vector3 position)
 275    {
 0276        if (buttonID != 0 || !isVoxelModelActivated || lastVoxelCreated == null)
 0277            return;
 278
 0279        lastVoxelPositionPressed = ConverPositionToVoxelPosition(lastVoxelCreated.transform.position);
 0280        mousePressed = true;
 0281        freeCameraMovement.SetCameraCanMove(false);
 0282        isCreatingMultipleVoxels = true;
 0283    }
 284
 285    public void SetVoxelSelected(DCLBuilderInWorldEntity decentralandEntityToEdit)
 286    {
 0287        lastVoxelCreated = decentralandEntityToEdit;
 0288        lastVoxelCreated.transform.localPosition = Vector3.zero;
 0289    }
 290
 291    public Vector3Int ConverPositionToVoxelPosition(Vector3 rawPosition)
 292    {
 0293        Vector3Int position = Vector3Int.zero;
 0294        position.x = Mathf.CeilToInt(rawPosition.x);
 0295        position.y = Mathf.CeilToInt(rawPosition.y);
 0296        position.z = Mathf.CeilToInt(rawPosition.z);
 0297        return position;
 298    }
 299
 300    bool IsVoxelAtValidPoint(VoxelPrefab voxelPrefab, List<DCLBuilderInWorldEntity> entitiesToCheck)
 301    {
 0302        if (!currentScene.IsInsideSceneBoundaries(voxelPrefab.meshRenderer.bounds))
 0303            return false;
 0304        Bounds bounds = voxelPrefab.meshRenderer.bounds;
 0305        bounds.size -= Vector3.one * VOXEL_BOUND_ERROR;
 0306        foreach (DCLBuilderInWorldEntity entity in entitiesToCheck)
 307        {
 0308            if (entity.rootEntity.meshesInfo == null || entity.rootEntity.meshesInfo.renderers == null)
 309                continue;
 0310            if (bounds.Intersects(entity.rootEntity.meshesInfo.mergedBounds))
 0311                return false;
 312        }
 313
 0314        bounds.size += Vector3.one * VOXEL_BOUND_ERROR;
 0315        return true;
 0316    }
 317}