internal float GetTreeYPos(InstanceState state, float deltaHeight, Vector3 newPosition, bool followTerrain, bool isClone = false) { TreeInstance[] trees = Singleton <TreeManager> .instance.m_trees.m_buffer; uint treeID = id.Tree; float y; float terrainHeight = Singleton <TerrainManager> .instance.SampleDetailHeight(newPosition); if (!MoveItTool.treeSnapping) { y = terrainHeight; } else if (trees[treeID].FixedHeight) { // If it's already fixed height, handle followTerrain // If the state is being cloned, don't use the terrain-height offset y = newPosition.y + (isClone ? 0 : yTerrainOffset); if (followTerrain) { y += terrainHeight - state.terrainHeight; } } else { // Snapping is on and it is not fixed height yet if (deltaHeight != 0) { trees[treeID].FixedHeight = true; y = terrainHeight + deltaHeight; yTerrainOffset = terrainHeight - state.terrainHeight; } else { y = terrainHeight; } } //Log.Debug($"{path}\nstate:{state.terrainHeight} tH-state:{terrainHeight - state.terrainHeight}, yTO:{yTerrainOffset}\n" + // $"ft:{followTerrain}, ts:{MoveItTool.treeSnapping}, fh:{trees[treeID].FixedHeight}, dh:{deltaHeight}\n" + // $"FRAME - newY:{newPosition.y}, oldY:{position.y}, diff:{newPosition.y - position.y}\n" + // $"ADJUST - adjY:{y}, newY:{newPosition.y}, diff:{y - newPosition.y}\n" + // $"TOTAL - adjY:{y}, oldY:{position.y}, diff:{y - position.y}\n" + // $"HEIGHT - adjY:{y}, terrainHeight:{terrainHeight}, diff:{y - terrainHeight}"); return(y); }
public void DoProcess() { Matrix4x4 matrix4x = default; foreach (Instance instance in m_clones) { if (instance.isValid) { InstanceState state = null; foreach (KeyValuePair <Instance, Instance> pair in m_origToClone) { if (pair.Value.id.RawData == instance.id.RawData) { if (pair.Value is MoveableSegment) { // Segments need original state because nodes move before clone's position is saved state = pair.Key.SaveToState(); } else { // Buildings need clone state to access correct subInstances. Others don't matter, but clone makes most sense state = pair.Value.SaveToState(); } break; } } if (state == null) { throw new NullReferenceException($"Original for cloned object not found."); } float faceDelta = getMirrorFacingDelta(state.angle, mirrorAngle); float posDelta = getMirrorPositionDelta(state.position, mirrorPivot, mirrorAngle); matrix4x.SetTRS(mirrorPivot, Quaternion.AngleAxis(posDelta * Mathf.Rad2Deg, Vector3.down), Vector3.one); instance.Transform(state, ref matrix4x, 0f, faceDelta, mirrorPivot, followTerrain); } } bool fast = MoveItTool.fastMove != Event.current.shift; UpdateArea(originalBounds, !fast || containsNetwork); UpdateArea(GetTotalBounds(false), !fast); }
public override Instance Clone(InstanceState instanceState, Dictionary <ushort, ushort> clonedNodes) { TreeState state = instanceState as TreeState; Instance cloneInstance = null; TreeInstance[] buffer = TreeManager.instance.m_trees.m_buffer; if (TreeManager.instance.CreateTree(out uint clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as TreeInfo, state.position, state.single)) { InstanceID cloneID = default; cloneID.Tree = clone; cloneInstance = new MoveableTree(cloneID); buffer[clone].FixedHeight = state.fixedHeight; } return(cloneInstance); }
public override void SetState(InstanceState state) { if (!(state is SegmentState segmentState)) { return; } ushort segment = id.NetSegment; segmentBuffer[segment].m_startDirection = segmentState.startDirection; segmentBuffer[segment].m_endDirection = segmentState.endDirection; UpdateSegmentBlocks(segment, ref segmentBuffer[segment]); netManager.UpdateNode(segmentBuffer[segment].m_startNode); netManager.UpdateNode(segmentBuffer[segment].m_endNode); MoveItTool.NS.SetSegmentModifiers(segment, segmentState); }
public override void RenderCloneGeometry(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { SegmentState state = instanceState as SegmentState; NetInfo netInfo = state.Info.Prefab as NetInfo; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } Bezier3 bezier; bezier.a = matrix4x.MultiplyPoint(state.startPosition - center); bezier.d = matrix4x.MultiplyPoint(state.endPosition - center); if (followTerrain) { bezier.a.y = bezier.a.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.a) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.startPosition); bezier.d.y = bezier.d.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.d) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.endPosition); } else { bezier.a.y = state.startPosition.y + deltaPosition.y; bezier.d.y = state.endPosition.y + deltaPosition.y; } Vector3 startDirection = newPosition - bezier.a; Vector3 endDirection = newPosition - bezier.d; startDirection.y = 0; endDirection.y = 0; startDirection.Normalize(); endDirection.Normalize(); //private static void RenderSegment(NetInfo info, NetSegment.Flags flags, Vector3 startPosition, Vector3 endPosition, Vector3 startDirection, Vector3 endDirection, bool smoothStart, bool smoothEnd) RenderSegment.Invoke(null, new object[] { netInfo, NetSegment.Flags.All, bezier.a, bezier.d, startDirection, -endDirection, state.smoothStart, state.smoothEnd }); }
public override void SetState(InstanceState state) { if (!(state is BuildingState buildingState)) { return; } ushort building = buildingState.instance.id.Building; buildingBuffer[building].m_flags = buildingState.flags; RelocateBuilding(building, ref buildingBuffer[building], buildingState.position, buildingState.angle); if (buildingState.subStates != null) { foreach (InstanceState subState in buildingState.subStates) { subState.instance.SetState(subState); } } }
public override void RenderCloneOverlay(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { PropState state = instanceState as PropState; PropInfo info = state.info as PropInfo; Randomizer randomizer = new Randomizer(state.instance.id.Prop); float scale = info.m_minScale + (float)randomizer.Int32(10000u) * (info.m_maxScale - info.m_minScale) * 0.0001f; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } float newAngle = state.angle + deltaAngle; PropTool.RenderOverlay(cameraInfo, info, newPosition, scale, newAngle, toolColor); }
public override void RenderCloneGeometry(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { TreeState state = instanceState as TreeState; TreeInfo info = state.info as TreeInfo; Randomizer randomizer = new Randomizer(state.instance.id.Tree); float scale = info.m_minScale + (float)randomizer.Int32(10000u) * (info.m_maxScale - info.m_minScale) * 0.0001f; float brightness = info.m_minBrightness + (float)randomizer.Int32(10000u) * (info.m_maxBrightness - info.m_minBrightness) * 0.0001f; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } TreeInstance.RenderInstance(cameraInfo, info, newPosition, scale, brightness, RenderManager.DefaultColorLocation); }
public override void Transform(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain) { BuildingState state = instanceState as BuildingState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaHeight; float terrainHeight = TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); if (followTerrain) { newPosition.y = newPosition.y + terrainHeight - state.terrainHeight; } // TODO: when should the flag be set? if (Mathf.Abs(terrainHeight - newPosition.y) > 0.01f) { AddFixedHeightFlag(id.Building); } else { RemoveFixedHeightFlag(id.Building); } Move(newPosition, state.angle + deltaAngle); if (state.subStates != null) { foreach (InstanceState subState in state.subStates) { Vector3 subPosition = subState.position - center; subPosition = matrix4x.MultiplyPoint(subPosition); subPosition.y = subState.position.y - state.position.y + newPosition.y; subState.instance.Move(subPosition, subState.angle + deltaAngle); } } }
public override Instance Clone(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes, Action action) { NodeState state = instanceState as NodeState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaHeight; if (followTerrain) { newPosition.y = newPosition.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition) - state.terrainHeight; } Instance cloneInstance = null; if (NetManager.instance.CreateNode(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo, newPosition, SimulationManager.instance.m_currentBuildIndex)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default; cloneID.NetNode = clone; nodeBuffer[clone].m_flags = state.flags; nodeBuffer[clone].CalculateNode(clone); nodeBuffer[clone].Info.m_netAI.GetNodeBuilding(clone, ref nodeBuffer[clone], out BuildingInfo newBuilding, out float heightOffset); nodeBuffer[clone].UpdateBuilding(clone, newBuilding, heightOffset); cloneInstance = new MoveableNode(cloneID); if (((NetNode)data).m_building > 0) { buildingBuffer[((NetNode)(cloneInstance.data)).m_building].m_flags = buildingBuffer[((NetNode)data).m_building].m_flags; } } return(cloneInstance); }
public override Instance Clone(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes) { SegmentState state = instanceState as SegmentState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); Instance cloneInstance = null; ushort startNode = state.startNode; ushort endNode = state.endNode; // Nodes should exist startNode = clonedNodes[startNode]; endNode = clonedNodes[endNode]; Vector3 startDirection = newPosition - nodeBuffer[startNode].m_position; Vector3 endDirection = newPosition - nodeBuffer[endNode].m_position; startDirection.y = 0; endDirection.y = 0; startDirection.Normalize(); endDirection.Normalize(); if (netManager.CreateSegment(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo, startNode, endNode, startDirection, endDirection, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, state.invert)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default(InstanceID); cloneID.NetSegment = clone; cloneInstance = new MoveableSegment(cloneID); } return(cloneInstance); }
public override void RenderCloneOverlay(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { if (MoveItTool.m_isLowSensitivity) { return; } BuildingState state = instanceState as BuildingState; BuildingInfo buildingInfo = state.Info.Prefab as BuildingInfo; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } float newAngle = state.angle + deltaAngle; buildingInfo.m_buildingAI.RenderBuildOverlay(cameraInfo, toolColor, newPosition, newAngle, default); BuildingTool.RenderOverlay(cameraInfo, buildingInfo, state.length, newPosition, newAngle, toolColor, false); if (buildingInfo.m_subBuildings != null && buildingInfo.m_subBuildings.Length != 0) { Matrix4x4 subMatrix4x = default; subMatrix4x.SetTRS(newPosition, Quaternion.AngleAxis(newAngle * Mathf.Rad2Deg, Vector3.down), Vector3.one); for (int i = 0; i < buildingInfo.m_subBuildings.Length; i++) { BuildingInfo buildingInfo2 = buildingInfo.m_subBuildings[i].m_buildingInfo; Vector3 position = subMatrix4x.MultiplyPoint(buildingInfo.m_subBuildings[i].m_position); float angle = buildingInfo.m_subBuildings[i].m_angle * 0.0174532924f + newAngle; buildingInfo2.m_buildingAI.RenderBuildOverlay(cameraInfo, toolColor, position, angle, default); BuildingTool.RenderOverlay(cameraInfo, buildingInfo2, 0, position, angle, toolColor, true); } } }
public override void LoadFromState(InstanceState state) { if (!(state is BuildingState buildingState)) { return; } ushort building = buildingState.instance.id.Building; buildingBuffer[building].m_flags = buildingState.flags; AddFixedHeightFlag(building); RelocateBuilding(building, ref buildingBuffer[building], buildingState.position, buildingState.angle); isSubInstance = buildingState.isSubInstance; if (buildingState.subStates != null) { foreach (InstanceState subState in buildingState.subStates) { subState.instance.LoadFromState(subState); } } buildingBuffer[building].m_flags = buildingState.flags; }
public override Instance Clone(InstanceState instanceState, Dictionary <ushort, ushort> clonedNodes) { NodeState state = instanceState as NodeState; MoveableNode cloneInstance = null; if (NetManager.instance.CreateNode(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo, state.position, SimulationManager.instance.m_currentBuildIndex)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default; cloneID.NetNode = clone; cloneInstance = new MoveableNode(cloneID); nodeBuffer[clone].m_flags = state.flags; // TODO: Clone pillar instead? nodeBuffer[clone].Info.m_netAI.GetNodeBuilding(clone, ref nodeBuffer[clone], out BuildingInfo newBuilding, out float heightOffset); nodeBuffer[clone].UpdateBuilding(clone, newBuilding, heightOffset); } return(cloneInstance); }
public override void Transform(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain) { NodeState state = instanceState as NodeState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaHeight; if (followTerrain) { newPosition.y = newPosition.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition) - state.terrainHeight; } Move(newPosition, 0); if (state.pillarState != null) { Vector3 subPosition = state.pillarState.position - center; subPosition = matrix4x.MultiplyPoint(subPosition); subPosition.y = state.pillarState.position.y - state.position.y + newPosition.y; state.pillarState.instance.Move(subPosition, state.pillarState.angle + deltaAngle); } }
public override Instance Clone(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes) { BuildingState state = instanceState as BuildingState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaHeight; float terrainHeight = TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); if (followTerrain) { newPosition.y = newPosition.y + terrainHeight - state.terrainHeight; } MoveableBuilding cloneInstance = null; BuildingInfo info = state.info as BuildingInfo; float newAngle = state.angle + deltaAngle; if (BuildingManager.instance.CreateBuilding(out ushort clone, ref SimulationManager.instance.m_randomizer, info, newPosition, newAngle, state.length, SimulationManager.instance.m_currentBuildIndex)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default(InstanceID); cloneID.Building = clone; cloneInstance = new MoveableBuilding(cloneID); if ((state.flags & Building.Flags.Completed) != Building.Flags.None) { buildingBuffer[clone].m_flags = buildingBuffer[clone].m_flags | Building.Flags.Completed; } if ((state.flags & Building.Flags.FixedHeight) != Building.Flags.None) { buildingBuffer[clone].m_flags = buildingBuffer[clone].m_flags | Building.Flags.FixedHeight; } // TODO: when should the flag be set? if (Mathf.Abs(terrainHeight - newPosition.y) > 0.01f) { AddFixedHeightFlag(clone); } else { RemoveFixedHeightFlag(clone); } if (info.m_subBuildings != null && info.m_subBuildings.Length != 0) { Matrix4x4 subMatrix4x = default(Matrix4x4); subMatrix4x.SetTRS(newPosition, Quaternion.AngleAxis(newAngle * Mathf.Rad2Deg, Vector3.down), Vector3.one); for (int i = 0; i < info.m_subBuildings.Length; i++) { BuildingInfo subInfo = info.m_subBuildings[i].m_buildingInfo; Vector3 subPosition = subMatrix4x.MultiplyPoint(info.m_subBuildings[i].m_position); float subAngle = info.m_subBuildings[i].m_angle * 0.0174532924f + newAngle; if (BuildingManager.instance.CreateBuilding(out ushort subClone, ref SimulationManager.instance.m_randomizer, subInfo, subPosition, subAngle, 0, SimulationManager.instance.m_currentBuildIndex)) { SimulationManager.instance.m_currentBuildIndex++; if (info.m_subBuildings[i].m_fixedHeight) { buildingBuffer[subClone].m_flags = buildingBuffer[subClone].m_flags | Building.Flags.FixedHeight; } } if (clone != 0 && subClone != 0) { buildingBuffer[clone].m_subBuilding = subClone; buildingBuffer[subClone].m_parentBuilding = clone; buildingBuffer[subClone].m_flags = buildingBuffer[subClone].m_flags | Building.Flags.Untouchable; clone = subClone; } } } } return(cloneInstance); }
public abstract void SetState(InstanceState state);
public abstract void Transform(InstanceState state, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain);
public override void RenderCloneGeometry(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { RenderCloneGeometryImplementation(instanceState, ref matrix4x, deltaPosition, deltaAngle, center, followTerrain, cameraInfo); }
public abstract Instance Clone(InstanceState state, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes);
public abstract Instance Clone(InstanceState state, Dictionary <ushort, ushort> clonedNodes);
public abstract void RenderCloneGeometry(InstanceState state, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor);
public override void Do() { if (selection.Count < 3) { return; } Dictionary <InstanceState, float> distances = new Dictionary <InstanceState, float>(); Bounds originalBounds = GetTotalBounds(false); Matrix4x4 matrix4x = default; GetExtremeObjects(out keyInstance[0], out keyInstance[1]); double angleToB = GetAngleBetweenPointsRads(PointA.position, PointB.position); foreach (InstanceState state in m_states) { Instance inst = state.instance; if (inst is MoveableSegment || inst == PointA || inst == PointB) { continue; } double angle = (GetAngleBetweenPointsRads(PointA.position, inst.position) - angleToB + (Mathf.PI * 2)) % (Mathf.PI * 2); float distance = Mathf.Cos((float)angle) * (inst.position - PointA.position).magnitude; distances.Add(state, distance); } IOrderedEnumerable <KeyValuePair <InstanceState, float> > sorted = distances.OrderBy(key => key.Value); Vector3 interval = (PointB.position - PointA.position) / (sorted.Count() + 1); float totalDistance = (PointB.position - PointA.position).magnitude; //string msg = $"{totalDistance}, {mode}"; //foreach (KeyValuePair<InstanceState, float> pair in distances) //{ // Instance inst = pair.Key.instance; // float d = pair.Value; // msg += $"\n{inst}:{d}"; //} //Log.Debug(msg); Vector3 cumulative = Vector3.zero; foreach (KeyValuePair <InstanceState, float> pair in sorted) { InstanceState state = pair.Key; float heightDelta; if (mode == Modes.Spaced) { cumulative += interval; } else if (mode == Modes.Unspaced) { cumulative = (PointB.position - PointA.position) * (pair.Value / totalDistance); } if (followTerrain) { heightDelta = 0f; } else { heightDelta = (PointA.position.y - state.position.y) + cumulative.y; } matrix4x.SetTRS(PointA.position + cumulative, Quaternion.AngleAxis(0f, Vector3.down), Vector3.one); state.instance.Transform(state, ref matrix4x, heightDelta, 0f, state.position, followTerrain); } UpdateArea(originalBounds, true); UpdateArea(GetTotalBounds(false), true); }
public override void Transform(InstanceState state, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain) { Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); Move(newPosition, 0); }
public void DoProcess() { Dictionary <Instance, float> instanceRotations = new Dictionary <Instance, float>(); Matrix4x4 matrix4x = default; foreach (Instance instance in m_clones) { if (instance.isValid) { InstanceState state = null; foreach (KeyValuePair <Instance, Instance> pair in m_origToClone) { if (pair.Value.id.RawData == instance.id.RawData) { if (pair.Value is MoveableSegment) { // Segments need original state because nodes move before clone's position is saved state = pair.Key.SaveToState(); } else { // Buildings need clone state to access correct subInstances. Others don't matter, but clone makes most sense state = pair.Value.SaveToState(); } break; } } if (state == null) { throw new NullReferenceException($"Original for cloned object not found."); } float faceDelta = getMirrorFacingDelta(state.angle, mirrorAngle); float posDelta = getMirrorPositionDelta(state.position, mirrorPivot, mirrorAngle); instanceRotations[instance] = faceDelta; matrix4x.SetTRS(mirrorPivot, Quaternion.AngleAxis(posDelta * Mathf.Rad2Deg, Vector3.down), Vector3.one); instance.Transform(state, ref matrix4x, 0f, faceDelta, mirrorPivot, followTerrain); } } // Mirror integrations foreach (var item in m_stateToClone) { foreach (var data in item.Key.IntegrationData) { try { CallIntegration(data.Key, item.Value.id, data.Value, m_InstanceID_origToClone, instanceRotations[item.Value], mirrorAngle); //data.Key.Mirror(item.Value.id, data.Value, m_InstanceID_origToClone); } catch (MissingMethodException e) { Log.Debug($"Failed to find Mirror method, a mod {data.Key.Name} needs updated.\n{e}"); } catch (Exception e) { InstanceID sourceInstanceID = item.Key.instance.id; InstanceID targetInstanceID = item.Value.id; Log.Error($"integration {data.Key} Failed to paste from " + $"{sourceInstanceID.Type}:{sourceInstanceID.Index} to {targetInstanceID.Type}:{targetInstanceID.Index}"); DebugUtils.LogException(e); } } } bool fast = MoveItTool.fastMove != Event.current.shift; UpdateArea(originalBounds, !fast || ((TypeMask & TypeMasks.Network) != TypeMasks.None)); UpdateArea(GetTotalBounds(false), !fast); }
public override void RenderCloneOverlay(InstanceState state, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { }
public override void Transform(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain) { BuildingState state = instanceState as BuildingState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaHeight; float terrainHeight = TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); bool isFixed = GetFixedHeightFlag(id.Building); if (!isFixed) { AddFixedHeightFlag(id.Building); } if (followTerrain) { newPosition.y = newPosition.y + terrainHeight - state.terrainHeight; } AddFixedHeightFlag(id.Building); Move(newPosition, state.angle + deltaAngle); Matrix4x4 matrixSub = default; matrixSub.SetTRS(Vector3.zero, Quaternion.AngleAxis(deltaAngle * Mathf.Rad2Deg, Vector3.down), Vector3.one); if (state.subStates != null) { foreach (InstanceState subState in state.subStates) { Vector3 subOffset = (subState.position - center) - (state.position - center); Vector3 subPosition = TransformPosition + matrixSub.MultiplyPoint(subOffset); subPosition.y = subState.position.y - state.position.y + newPosition.y; subState.instance.Move(subPosition, subState.angle + deltaAngle); if (subState.instance is MoveableNode mn) { if (mn.Pillar != null) { mn.Pillar.Move(subPosition, subState.angle + deltaAngle); } } if (subState is BuildingState bs) { if (bs.subStates != null) { foreach (InstanceState subSubState in bs.subStates) { Vector3 subSubOffset = (subSubState.position - center) - (state.position - center); Vector3 subSubPosition = TransformPosition + matrixSub.MultiplyPoint(subSubOffset); subSubPosition.y = subSubState.position.y - state.position.y + newPosition.y; subSubState.instance.Move(subSubPosition, subSubState.angle + deltaAngle); if (subSubState.instance is MoveableNode mn2) { if (mn2.Pillar != null) { mn2.Pillar.Move(subSubPosition, subSubState.angle + deltaAngle); } } } } } } } if (!isFixed && Mathf.Abs(terrainHeight - newPosition.y) < 0.01f) { RemoveFixedHeightFlag(id.Building); } }