예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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 });
        }
예제 #6
0
        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);
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
                }
            }
        }
예제 #13
0
        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;
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
 public abstract void SetState(InstanceState state);
예제 #18
0
 public abstract void Transform(InstanceState state, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain);
예제 #19
0
 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);
 }
예제 #20
0
 public abstract Instance Clone(InstanceState state, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes);
예제 #21
0
 public abstract Instance Clone(InstanceState state, Dictionary <ushort, ushort> clonedNodes);
예제 #22
0
 public abstract void RenderCloneGeometry(InstanceState state, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor);
예제 #23
0
        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);
        }
예제 #24
0
        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);
        }
예제 #25
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);
        }
예제 #26
0
 public override void RenderCloneOverlay(InstanceState state, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor)
 {
 }
예제 #27
0
        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);
            }
        }