private void RaycastAllTerrainObjects(Ray ray, List <GameObjectRayHit> terrainHits) { // Can we pick terrains? if (!IsObjectPickMaskFlagSet(MouseCursorObjectPickFlags.ObjectTerrain)) { // We will use Unity's 'Physics' API for terrain picking because it is reasonable enough // to expect users to attach terrain colliders to their terrain objects. RaycastHit[] rayHits = Physics.RaycastAll(ray); if (rayHits.Length != 0) { // Identify all terrain colliders which were picked foreach (RaycastHit rayHit in rayHits) { // Picked a terrain collider? if (rayHit.collider.GetType() == typeof(TerrainCollider)) { // Create a game object hit instance and add it to the list var terrainRayHit = new TerrainRayHit(ray, rayHit); var gameObjectRayHit = new GameObjectRayHit(ray, rayHit.collider.gameObject, null, null, terrainRayHit, null); terrainHits.Add(gameObjectRayHit); } } } } }
private bool ValidateGameObjectRayHit(GameObjectRayHit gameObjectRayHit) { if (gameObjectRayHit.WasBoxHit) { return(false); } return(true); }
private void AcquireCursorRayHitOnStrokeStart() { if (HasCursorPickedAnything()) { _strokeGameObjectRayHit = _cursorRayHit.ClosestObjectRayHit; _strokeGridCellRayHit = _cursorRayHit.GridCellRayHit; } }
public void FromGameObjectRayHit(GameObjectRayHit gameObjectRayHit) { _isValid = false; if (!ValidateGameObjectRayHit(gameObjectRayHit)) { return; } ExtractData(gameObjectRayHit); }
private void ExtractData(GameObjectRayHit objectRayHit) { if (objectRayHit.WasBoxHit) { _isValid = true; _mouseCursorPickPoint = objectRayHit.HitPoint; CalculateSurfaceQuad(objectRayHit.ObjectBoxHit); _objectBoxSnapSurfaceGrid.FromXZOrientedQuad(_surfaceQuad); _type = SnapSurfaceType.ObjectCollider; _surfaceObject = objectRayHit.HitObject; } }
public MouseCursorRayHit(GridCellRayHit gridCellRayHit, List <GameObjectRayHit> sortedObjectRayHits) { _gridCellRayHit = gridCellRayHit; _sortedObjectRayHits = sortedObjectRayHits != null ? new List <GameObjectRayHit>(sortedObjectRayHits) : new List <GameObjectRayHit>(); int firstLightHit = _sortedObjectRayHits.FindIndex(item => item.HitObject.HasLight()); int firstParticleSystemHit = _sortedObjectRayHits.FindIndex(item => item.HitObject.HasParticleSystem()); if (firstLightHit >= 0) { _wasLightObjectHit = true; _closestLightObjectHit = _sortedObjectRayHits[firstLightHit]; } if (firstParticleSystemHit >= 0) { _wasParticleSystemHit = true; _closestParticleSystemObjectHit = _sortedObjectRayHits[firstParticleSystemHit]; } }
private void ExtractData(GameObjectRayHit gameObjectRayHit) { _isValid = true; _mouseCursorPickPoint = gameObjectRayHit.HitPoint; _normal = gameObjectRayHit.HitNormal; if (gameObjectRayHit.WasTerrainHit) { _type = DecorPaintStrokeSurfaceType.Terrain; } else if (gameObjectRayHit.WasSpriteHit) { _type = DecorPaintStrokeSurfaceType.Sprite; } else { _type = DecorPaintStrokeSurfaceType.Mesh; } _surfaceObject = gameObjectRayHit.HitObject; }
/// <summary> /// Performs a raycast and returns a list of hits for all sprite objects intersected /// by the ray. /// </summary> public List <GameObjectRayHit> RaycastAllSprite(Ray ray) { // First, retrieve a list of the sphere tree nodes which were hit by the ray. // If no nodes were hit, it means no object was hit either. List <SphereTreeNodeRayHit <GameObject> > allNodeHits = _sphereTree.RaycastAll(ray); if (allNodeHits.Count == 0) { return(new List <GameObjectRayHit>()); } // Loop through all nodes which were hit by the ray. For each node, we have to detect // if the ray hits the sprite object. var gameObjectHits = new List <GameObjectRayHit>(); foreach (SphereTreeNodeRayHit <GameObject> nodeHit in allNodeHits) { // Retrieve the object which resides in the node GameObject gameObject = nodeHit.HitNode.Data; if (gameObject == null || !gameObject.activeInHierarchy) { continue; } if (!gameObject.HasSpriteRendererWithSprite()) { continue; } // If the ray intersects the object's sprite, add the hit to the list GameObjectRayHit gameObjectRayHit = null; if (gameObject.RaycastSprite(ray, out gameObjectRayHit)) { gameObjectHits.Add(gameObjectRayHit); } } return(gameObjectHits); }
public void FromMouseCursorRayHit(MouseCursorRayHit cursorRayHit) { _isValid = false; if (!cursorRayHit.WasAnythingHit) { return; } if (cursorRayHit.WasAnObjectHit) { GameObjectRayHit objectRayHit = FindClosestHitObjectWhichCanBeUsedAsPaintSurface(cursorRayHit); if (objectRayHit != null && ValidateGameObjectRayHit(objectRayHit)) { ExtractData(objectRayHit); } } if (!_isValid && cursorRayHit.WasACellHit) { ExtractData(cursorRayHit.GridCellRayHit); } }
private void CreateSurfaceColliderProjector() { MouseCursorRayHit brushCursorRayHit = _workingBrushCircle.CursorRayHit; if (brushCursorRayHit.WasAnObjectHit) { GameObjectRayHit objectRayHit = brushCursorRayHit.ClosestObjectRayHit; if (objectRayHit.WasMeshHit) { _surfaceColliderProjector = new PointsOnColliderProjector(objectRayHit.ObjectMeshHit.HitCollider, _workingBrushCircle.Plane); } else if (objectRayHit.WasTerrainHit) { _surfaceColliderProjector = new PointsOnColliderProjector(objectRayHit.ObjectTerrainHit.HitCollider, _workingBrushCircle.Plane); } else if (objectRayHit.WasSpriteHit) { _surfaceColliderProjector = new PointsOnColliderProjector(objectRayHit.ObjectSpriteHit.HitCollider, _workingBrushCircle.Plane); } } }
public void Update() { if (IsActive) { if (AllShortcutCombos.Instance.GrabRotateSelection.IsActive()) { _state = State.Rotating; } else if (AllShortcutCombos.Instance.GrabScaleSelection.IsActive()) { if (_state != State.Scaling) { _objectToWorldScale.Clear(); foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject != null) { _objectToWorldScale.Add(grabbedObject, grabbedObject.transform.lossyScale); } } _cursorPosAtScaleBegin = MouseCursor.Instance.Position; _state = State.Scaling; } } else { // Need to reset the anchor relationships because the cursor was moved without // the objects following it. if (_state == State.Rotating || _state == State.Scaling) { _objectToPivotDir.Clear(); foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject != null) { _objectToPivotDir.Add(grabbedObject, grabbedObject.transform.position - _surfaceHitPoint); } } } _state = State.Moving; } _currentCursorRayHit = GetCursorRayHit(); if (!_currentCursorRayHit.WasAnythingHit) { return; } if (_currentCursorRayHit.WasAnythingHit) { if (_currentCursorRayHit.WasAnObjectHit) { _surfaceHitPoint = _currentCursorRayHit.ClosestObjectRayHit.HitPoint; } else { _surfaceHitPoint = _currentCursorRayHit.GridCellRayHit.HitPoint; } } if (_state == State.Moving || _objectToSurfaceInfo.Count == 0) { if (_currentCursorRayHit.WasAnObjectHit) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); GameObjectRayHit objectRayHit = _currentCursorRayHit.ClosestObjectRayHit; foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject == null) { continue; } Transform objectTransform = grabbedObject.transform; objectTransform.position = objectRayHit.HitPoint + _objectToPivotDir[grabbedObject]; if (objectRayHit.WasTerrainHit) { Ray ray = new Ray(grabbedObject.GetHierarchyWorldOrientedBox().Center + Vector3.up, -Vector3.up); GameObjectRayHit sitPointHit = null; if (objectRayHit.HitObject.RaycastTerrainReverseIfFail(ray, out sitPointHit)) { Plane surfacePlane = new Plane(sitPointHit.HitNormal, sitPointHit.HitPoint); if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, sitPointHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(surfacePlane); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * sitPointHit.HitNormal; } if (_grabSettings.EmbedInSurfaceWhenNoAlign && !_grabSettings.AlignAxis) { grabbedObject.EmbedInSurfaceByVertex(-Vector3.up, objectRayHit.HitObject); } ObjectSurfaceInfo surfaceInfo = new ObjectSurfaceInfo(); surfaceInfo.SurfacePlane = surfacePlane; surfaceInfo.SitPoint = sitPointHit.HitPoint; SetObjectSurfaceInfo(grabbedObject, surfaceInfo); } } else if (objectRayHit.WasMeshHit) { Ray ray = new Ray(grabbedObject.GetHierarchyWorldOrientedBox().Center + objectRayHit.HitNormal * 2.0f, -objectRayHit.HitNormal); GameObjectRayHit sitPointHit = null; if (objectRayHit.HitObject.RaycastMeshReverseIfFail(ray, out sitPointHit)) { Plane surfacePlane = new Plane(sitPointHit.HitNormal, sitPointHit.HitPoint); if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, sitPointHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(surfacePlane); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * sitPointHit.HitNormal; } if (_grabSettings.EmbedInSurfaceWhenNoAlign && !_grabSettings.AlignAxis) { grabbedObject.EmbedInSurfaceByVertex(-sitPointHit.HitNormal, objectRayHit.HitObject); } ObjectSurfaceInfo surfaceInfo = new ObjectSurfaceInfo(); surfaceInfo.SurfacePlane = surfacePlane; surfaceInfo.SitPoint = sitPointHit.HitPoint; SetObjectSurfaceInfo(grabbedObject, surfaceInfo); } } } } else if (_currentCursorRayHit.WasACellHit) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); GridCellRayHit cellRayHit = _currentCursorRayHit.GridCellRayHit; foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject == null) { continue; } Transform objectTransform = grabbedObject.transform; objectTransform.position = cellRayHit.HitPoint + _objectToPivotDir[grabbedObject]; Plane surfacePlane = new Plane(cellRayHit.HitNormal, cellRayHit.HitPoint); Vector3 sitPoint = surfacePlane.ProjectPoint(grabbedObject.GetWorldOrientedBox().Center); if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, cellRayHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(surfacePlane); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * cellRayHit.HitNormal; } ObjectSurfaceInfo surfaceInfo = new ObjectSurfaceInfo(); surfaceInfo.SurfacePlane = surfacePlane; surfaceInfo.SitPoint = sitPoint; SetObjectSurfaceInfo(grabbedObject, surfaceInfo); } } } else if (_state == State.Rotating) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); float rotationSensitivity = _grabSettings.RotationSensitivity; foreach (var grabbedObject in _grabbedObjects) { if (!_objectToSurfaceInfo.ContainsKey(grabbedObject)) { continue; } var surfaceInfo = _objectToSurfaceInfo[grabbedObject]; OrientedBox worldOOBB = grabbedObject.GetHierarchyWorldOrientedBox(); grabbedObject.RotateHierarchyBoxAroundPoint(MouseCursor.Instance.OffsetSinceLastMouseMove.x * rotationSensitivity, _grabSettings.AlignAxis ? surfaceInfo.SurfacePlane.normal : Vector3.up, worldOOBB.Center); } } else if (_state == State.Scaling) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); Vector2 currentCursorPos = MouseCursor.Instance.Position; Vector2 cursorOffsetFromScaleBegin = currentCursorPos - _cursorPosAtScaleBegin; float scaleFactor = 1.0f + _grabSettings.ScaleSensitivity * cursorOffsetFromScaleBegin.x; foreach (var grabbedObject in _grabbedObjects) { if (!_objectToSurfaceInfo.ContainsKey(grabbedObject) || !_objectToWorldScale.ContainsKey(grabbedObject)) { continue; } var surfaceInfo = _objectToSurfaceInfo[grabbedObject]; grabbedObject.SetHierarchyWorldScaleByPivotPoint(_objectToWorldScale[grabbedObject] * scaleFactor, surfaceInfo.SitPoint); } } } }
private void ResetStrokePickInfo() { _strokeGameObjectRayHit = null; _strokeGridCellRayHit = null; }
private void AdjustShapeWhenSittingOnTerrain(GameObjectRayHit objectRayHit) { Normal = Vector3.up; Center = objectRayHit.HitPoint; }
public void Update() { if (IsActive) { _currentCursorRayHit = GetCursorRayHit(); if (!_currentCursorRayHit.WasAnythingHit) { return; } if (_currentCursorRayHit.WasAnObjectHit) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); GameObjectRayHit objectRayHit = _currentCursorRayHit.ClosestObjectRayHit; _surfaceHitPoint = objectRayHit.HitPoint; foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject == null) { continue; } Transform objectTransform = grabbedObject.transform; objectTransform.position = objectRayHit.HitPoint + _objectToPivotDir[grabbedObject]; if (objectRayHit.WasTerrainHit) { Ray ray = new Ray(grabbedObject.GetHierarchyWorldOrientedBox().Center + Vector3.up, -Vector3.up); GameObjectRayHit sitPointHit = null; if (objectRayHit.HitObject.RaycastTerrainReverseIfFail(ray, out sitPointHit)) { if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, sitPointHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(new Plane(sitPointHit.HitNormal, sitPointHit.HitPoint)); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * sitPointHit.HitNormal; } if (_grabSettings.EmbedInSurfaceWhenNoAlign && !_grabSettings.AlignAxis) { grabbedObject.EmbedInSurfaceByVertex(-Vector3.up, objectRayHit.HitObject); } } } else if (objectRayHit.WasMeshHit) { Ray ray = new Ray(grabbedObject.GetHierarchyWorldOrientedBox().Center + objectRayHit.HitNormal * 2.0f, -objectRayHit.HitNormal); GameObjectRayHit sitPointHit = null; if (objectRayHit.HitObject.RaycastMeshReverseIfFail(ray, out sitPointHit)) { if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, sitPointHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(new Plane(sitPointHit.HitNormal, sitPointHit.HitPoint)); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * sitPointHit.HitNormal; } if (_grabSettings.EmbedInSurfaceWhenNoAlign && !_grabSettings.AlignAxis) { grabbedObject.EmbedInSurfaceByVertex(-sitPointHit.HitNormal, objectRayHit.HitObject); } } } } } else if (_currentCursorRayHit.WasACellHit) { GameObjectExtensions.RecordObjectTransformsForUndo(_grabbedObjects); GridCellRayHit cellRayHit = _currentCursorRayHit.GridCellRayHit; _surfaceHitPoint = cellRayHit.HitPoint; foreach (var grabbedObject in _grabbedObjects) { if (grabbedObject == null) { continue; } Transform objectTransform = grabbedObject.transform; objectTransform.position = cellRayHit.HitPoint + _objectToPivotDir[grabbedObject]; if (_grabSettings.AlignAxis) { AxisAlignment.AlignObjectAxis(grabbedObject, _grabSettings.AlignmentAxis, cellRayHit.HitNormal); } grabbedObject.PlaceHierarchyOnPlane(new Plane(cellRayHit.HitNormal, cellRayHit.HitPoint)); if (!_grabSettings.EmbedInSurfaceWhenNoAlign || _grabSettings.AlignAxis) { objectTransform.position += _grabSettings.OffsetFromSurface * cellRayHit.HitNormal; } } } } }
public void UpdateForMouseMovement() { if (!_isActive) { return; } if (MouseButtonStates.Instance.IsMouseButtonDown(MouseButton.Left)) { _state = ObjectVertexSnapSessionState.SnapToDestination; } else { _state = ObjectVertexSnapSessionState.SelectSourceVertex; } if (_state == ObjectVertexSnapSessionState.SelectSourceVertex) { if (_sourceObjects == null || _sourceObjects.Count == 0) { _objectMask.ObjectCollectionMask.UnmaskAll(); MouseCursorRayHit cursorRayHit = GetCursorRayHit(); if (cursorRayHit.WasAnObjectHit) { GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit; MeshRayHit meshRayHit = objectRayHit.ObjectMeshHit; if (meshRayHit != null) { Octave3DMesh octaveMesh = meshRayHit.HitMesh; Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex); sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix); _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint); _sourceObject = objectRayHit.HitObject; _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf()); } else { SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>(); if (spriteRenderer != null) { _sourceObject = objectRayHit.HitObject; _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint); _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf()); } } } } else { MouseCursorRayHit cursorRayHit = GetCursorRayHit(); if (cursorRayHit.WasAnObjectHit) { GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit; MeshRayHit meshRayHit = objectRayHit.ObjectMeshHit; if (meshRayHit != null) { Octave3DMesh octaveMesh = meshRayHit.HitMesh; Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex); sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix); _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint); } else { SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>(); if (spriteRenderer != null) { _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint); } } } foreach (var parent in _sourceParents) { _objectMask.ObjectCollectionMask.Mask(parent.GetAllChildrenIncludingSelf()); } } } else { MouseCursorRayHit cursorRayHit = GetCursorRayHit(); if (cursorRayHit.WasAnythingHit) { bool useGridCellHit = false; if (!cursorRayHit.WasAnObjectHit) { useGridCellHit = true; } else if (cursorRayHit.WasAnObjectHit && cursorRayHit.WasACellHit) { float gridCellHitEnter = cursorRayHit.GridCellRayHit.HitEnter; float objectHitEnter = cursorRayHit.ClosestObjectRayHit.HitEnter; if (gridCellHitEnter < Mathf.Max(0.0f, (objectHitEnter - 1e-3f))) { useGridCellHit = true; } } if (useGridCellHit) { XZGridCell hitCell = cursorRayHit.GridCellRayHit.HitCell; XZOrientedQuad3D cellQuad = hitCell.Quad; _destinationObject = null; _destinationGridCell = hitCell; _snapPosition = cellQuad.GetPointClosestToPoint(cursorRayHit.GridCellRayHit.HitPoint, true); SnapToDestination(); } else { GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit; MeshRayHit meshRayHit = objectRayHit.ObjectMeshHit; if (meshRayHit != null) { _destinationObject = objectRayHit.HitObject; Triangle3D destinationTriangle = meshRayHit.HitMesh.GetTriangle(meshRayHit.HitTriangleIndex); destinationTriangle.TransformPoints(_destinationObject.transform.localToWorldMatrix); _destinationGridCell = null; _snapPosition = destinationTriangle.GetPointClosestToPoint(meshRayHit.HitPoint); SnapToDestination(); } else { SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>(); if (spriteRenderer != null) { _destinationGridCell = null; _destinationObject = objectRayHit.HitObject; _snapPosition = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint); SnapToDestination(); } } } } } }
public List <ObjectPlacementData> Calculate() { if (_block == null || _block.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene) { return(new List <ObjectPlacementData>()); } Prefab placementGuidePrefab = ObjectPlacementGuide.Instance.SourcePrefab; Vector3 placementGuideWorldScale = ObjectPlacementGuide.Instance.WorldScale; Quaternion placementGuideWorldRotation = ObjectPlacementGuide.Instance.WorldRotation; float objectMissChance = _block.Settings.ManualConstructionSettings.ObjectMissChance; ObjectRotationRandomizationSettings blockObjectRotationRandomizationSettings = _block.Settings.ManualConstructionSettings.ObjectRotationRandomizationSettings; bool randomizeRotations = blockObjectRotationRandomizationSettings.RandomizeRotation; Vector3 objectOffsetAlongExtensionPlaneNormal = _block.Settings.ManualConstructionSettings.OffsetAlongGrowDirection * _block.ExtensionPlane.normal; bool allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForBlockPlacement; bool randomizePrefabs = _block.Settings.ManualConstructionSettings.RandomizePrefabs; PrefabCategory activePrefabCategory = PrefabCategoryDatabase.Get().ActivePrefabCategory; ObjectPlacementBlockProjectionSettings projectionSettings = _block.Settings.BlockProjectionSettings; bool canProject = projectionSettings.ProjectOnSurface && (projectionSettings.CanProjectOnMesh || projectionSettings.CanProjectOnTerrain); var objectPlacementDataInstances = new List <ObjectPlacementData>(_block.NumberOfSegments * 10); for (int segmentIndex = 0; segmentIndex < _block.NumberOfSegments; ++segmentIndex) { ObjectPlacementBoxStackSegment segment = _block.GetSegmentByIndex(segmentIndex); for (int stackIndex = 0; stackIndex < segment.NumberOfStacks; ++stackIndex) { ObjectPlacementBoxStack stack = segment.GetStackByIndex(stackIndex); if (stack.IsOverlappedByAnotherStack || stack.NumberOfBoxes == 0) { continue; } Vector3 projectionOffset = Vector3.zero; Vector3 projectionDirection = Vector3.zero; Quaternion prjAlignRotation = Quaternion.identity; GameObjectRayHit projectionSurfaceHit = null; if (canProject) { Vector3 rayOrigin = stack.GetBoxByIndex(0).Center; Vector3 rayDir = Vector3.zero; if (projectionSettings.ProjectionDirection == ObjectBlockProjectionDir.BlockUp) { rayDir = _block.ExtensionPlane.normal; } else { rayDir = -_block.ExtensionPlane.normal; } projectionDirection = rayDir; Ray ray = new Ray(rayOrigin, rayDir); GameObjectRayHit closestMeshHit = null; GameObjectRayHit closestTerrainHit = null; if (projectionSettings.CanProjectOnMesh) { closestMeshHit = Octave3DScene.Get().RaycastAllMeshClosest(ray); } if (projectionSettings.CanProjectOnTerrain) { closestTerrainHit = Octave3DScene.Get().RaycastAllTerainsClosest(ray); } // Ignore stack if no surface was found and non-projectables must be rejected if (closestMeshHit == null && closestTerrainHit == null) { if (projectionSettings.RejectNonProjectables) { continue; } } else { projectionSurfaceHit = closestMeshHit; if (closestMeshHit == null || (closestTerrainHit != null && closestMeshHit.HitEnter > closestTerrainHit.HitEnter)) { projectionSurfaceHit = closestTerrainHit; } } if (projectionSurfaceHit != null) { ObjectPlacementBox projectionBox = stack.GetBoxByIndex(0); projectionOffset = projectionSurfaceHit.HitPoint - stack.GetBoxByIndex(0).Center; if (projectionOffset.sqrMagnitude > (projectionSurfaceHit.HitPoint - stack.GetBoxByIndex(stack.NumberOfBoxes - 1).Center).sqrMagnitude) { projectionBox = stack.GetBoxByIndex(stack.NumberOfBoxes - 1); projectionOffset = projectionSurfaceHit.HitPoint - projectionBox.Center; } if (!projectionSettings.AlignToSurfaceNormal) { var oobb = projectionBox.OrientedBox; Vector3 oldCenter = oobb.Center; GameObjectExtensions.EmbedObjectBoxInSurface(oobb, projectionDirection, projectionSurfaceHit.HitObject); projectionOffset = oobb.Center - oldCenter; } } } for (int stackBoxIndex = 0; stackBoxIndex < stack.NumberOfBoxes; ++stackBoxIndex) { ObjectPlacementBox box = stack.GetBoxByIndex(stackBoxIndex); if (box.IsHidden) { continue; } if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementBlockManualConstructionSettings.MinObjectMissChance, ObjectPlacementBlockManualConstructionSettings.MaxObjectMissChance)) { continue; } if (!allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true)) { continue; } Quaternion worldRotation = placementGuideWorldRotation; if (randomizeRotations) { worldRotation = ObjectRotationRandomization.GenerateRandomRotationQuaternion(blockObjectRotationRandomizationSettings); } Vector3 worldScale = placementGuideWorldScale; Prefab prefab = placementGuidePrefab; if (randomizePrefabs && activePrefabCategory.NumberOfPrefabs != 0) { int randomPrefabIndex = UnityEngine.Random.Range(0, activePrefabCategory.NumberOfPrefabs); Prefab randomPrefab = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex); if (randomPrefab != null && randomPrefab.UnityPrefab != null) { prefab = activePrefabCategory.GetPrefabByIndex(randomPrefabIndex); worldScale = prefab.UnityPrefab.transform.lossyScale; } } Vector3 boxCenter = box.Center + objectOffsetAlongExtensionPlaneNormal + projectionOffset; if (projectionSurfaceHit != null) { if (projectionSettings.AlignToSurfaceNormal) { worldRotation = AxisAlignment.CalculateRotationQuaternionForAxisAlignment(worldRotation, projectionSettings.AlignmentAxis, projectionSurfaceHit.HitNormal); OrientedBox prefabWorldOOBB = prefab.UnityPrefab.GetHierarchyWorldOrientedBox(); Vector3 oobbSize = prefabWorldOOBB.ScaledSize; int axisIndex = (int)((int)(projectionSettings.AlignmentAxis) * 0.5f); boxCenter = projectionSurfaceHit.HitPoint + projectionSurfaceHit.HitNormal * oobbSize[axisIndex] * 0.5f + (oobbSize[axisIndex] * stackBoxIndex * projectionSurfaceHit.HitNormal); } } var objectPlacementData = new ObjectPlacementData(); objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(prefab, boxCenter, worldScale, worldRotation); objectPlacementData.WorldScale = worldScale; objectPlacementData.WorldRotation = worldRotation; objectPlacementData.Prefab = prefab; objectPlacementDataInstances.Add(objectPlacementData); } } } return(objectPlacementDataInstances); }
private void AdjustShapeWhenSittingOnSprite(GameObjectRayHit objectRayHit) { Normal = objectRayHit.HitNormal; Center = objectRayHit.HitPoint; }