コード例 #1
0
ファイル: EntityModule.cs プロジェクト: manups4e/Atlas
        public void CallBeginOperation(AtlasEntity entity, int id)
        {
            Entity = entity;
            Id     = id;

            Begin(entity, id);
        }
コード例 #2
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 1)
                {
                    Chat.SendLocalMessage("Voice Chat",
                                          Function.Call <float>(Hash.NETWORK_GET_TALKER_PROXIMITY).ToString(CultureInfo.InvariantCulture),
                                          Color.FromArgb(0, 0, 255));

                    return;
                }

                float range;

                try
                {
                    range = float.Parse(arguments.ElementAt(0));
                }
                catch (Exception)
                {
                    range = 0f;
                }

                Function.Call(Hash.NETWORK_CLEAR_VOICE_CHANNEL);
                Function.Call(Hash.NETWORK_SET_TALKER_PROXIMITY, range);

                Chat.SendLocalMessage("Voice Chat", $"Ändrade voicechat proximity till {range}",
                                      Color.FromArgb(0, 0, 255));
            }
コード例 #3
0
            public async void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                try
                {
                    if (arguments.Count <= 0)
                    {
                        return;
                    }

                    var model = new Model(API.GetHashKey(arguments.ElementAt(0)));

                    if (!model.IsValid || !model.IsVehicle)
                    {
                        return;
                    }

                    var position = entity.Position;
                    var vehicle  = await World.CreateVehicle(model, position.AsVector(), position.Heading);

                    entity.Task.WarpIntoVehicle(vehicle, VehicleSeat.Driver);
                }
                catch (Exception)
                {
                    // Ignored
                }
            }
コード例 #4
0
ファイル: EntityNetworkModule.cs プロジェクト: manups4e/Atlas
 protected override void Begin(AtlasEntity entity, int id)
 {
     if (!API.NetworkGetEntityIsNetworked(id))
     {
         API.NetworkRegisterEntityAsNetworked(id);
     }
 }
コード例 #5
0
ファイル: EntityNetworkModule.cs プロジェクト: manups4e/Atlas
        public static AtlasEntity GetEntity(int id)
        {
            var entity = new AtlasEntity(API.NetworkGetEntityFromNetworkId(id));

            entity.InstallModule("Network", new EntityNetworkModule());

            return(entity);
        }
コード例 #6
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                var position = entity.Position;
                var title    = arguments.Count > 1 ? string.Join(" ", arguments.Skip(1)) : "Position";
                var log      =
                    $"[Developer] {title}: new Position({position.X}f, {position.Y}f, {position.Z}f, {position.Heading}f)";

                Logger.Info(log);
            }
コード例 #7
0
            public async void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 2)
                {
                    return;
                }

                await entity.Task.PlayAnimation(arguments[0], arguments[1], 8f, -8f, -1, AnimationFlags.None, 0);
            }
コード例 #8
0
                public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
                {
                    API.ClearPedTasksImmediately(entity.Id);
                    API.ClearPedSecondaryTask(entity.Id);
                    API.SetNuiFocus(false, false);

                    World.GetAllProps().Where(self => self.IsAttachedTo(Entity.FromHandle(entity.Id))).ToList()
                    .ForEach(self => self.Detach());

                    Chat.SendGlobalMessage("Reload", "Laddade om karaktären!", Color.FromArgb(255, 0, 0));
                }
コード例 #9
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 2)
                {
                    Chat.SendLocalMessage(Title, Usage, Color.FromArgb(255, 0, 0));

                    return;
                }

                int balance;

                try
                {
                    balance = Convert.ToInt32(arguments.ElementAt(1));
                }
                catch (FormatException)
                {
                    Chat.SendLocalMessage(Title, InvalidAmount, Color.FromArgb(255, 0, 0));

                    return;
                }

                switch (arguments.ElementAt(0).ToUpper())
                {
                case "ADD":
                    player.Character.Cash += balance;

                    Chat.SendLocalMessage(Title,
                                          $"{CorrectedCash}{player.Character.Cash})", Color.FromArgb(255, 0, 0));

                    break;

                case "SET":
                    player.Character.Cash = balance;
                    Chat.SendLocalMessage(Title,
                                          $"{CorrectedCash}{player.Character.Cash})", Color.FromArgb(255, 0, 0));

                    break;

                case "REMOVE":
                    player.Character.Cash -= balance;
                    Chat.SendLocalMessage(Title,
                                          $"{CorrectedCash}{player.Character.Cash})", Color.FromArgb(255, 0, 0));

                    break;

                default:
                    Chat.SendLocalMessage(Title,
                                          $"{NotFoundSubcommand}{arguments.ElementAt(0)}", Color.FromArgb(255, 0, 0));

                    break;
                }
            }
コード例 #10
0
ファイル: RoleplayChat.cs プロジェクト: manups4e/Atlas
                public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
                {
                    var manager = ActionMessageManager.GetModule();

                    manager.Messages.Add(new ActionMessageManager.ActionMessage
                    {
                        Seed    = Seed.Generate(),
                        Sender  = API.GetPlayerServerId(API.PlayerId()),
                        Message = string.Join(" ", arguments)
                    });
                    manager.Commit();
                }
コード例 #11
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 1)
                {
                    Chat.SendLocalMessage(Title, Usage, Color.FromArgb(255, 0, 0));

                    return;
                }

                switch (arguments.ElementAt(0).ToUpper())
                {
                case "SET":
                    if (arguments.Count < 3)
                    {
                        Chat.SendLocalMessage(Title, Usage, Color.FromArgb(255,
                                                                           0, 0));

                        return;
                    }

                    var jobName = arguments[1];
                    var jobRole = 0;

                    try
                    {
                        jobRole = int.Parse(arguments[2]);
                    }
                    catch (Exception)
                    {
                        // Ignored
                    }

                    Enum.TryParse <Employment>(jobName, true, out var job);

                    var character = Cache.Character;

                    character.Metadata.Employment     = job;
                    character.Metadata.EmploymentRole = jobRole;

                    Chat.SendLocalMessage(Title,
                                          $"Anställde {character.Fullname} hos {job.ToString()} - {jobRole}",
                                          Color.FromArgb(255, 0, 0));

                    break;

                default:
                    Chat.SendLocalMessage(Title,
                                          $"Kunde inte hitta kommando: {arguments.ElementAt(0)}", Color.FromArgb(255, 0, 0));

                    break;
                }
            }
コード例 #12
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                var vehicle = entity.Vehicle;

                if (vehicle == null)
                {
                    return;
                }

                vehicle.Wash();
                vehicle.Repair();
                vehicle.PlaceOnGround();
            }
コード例 #13
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                StyleManager.GetModule().OpenStyleChange(Cache.Character.Style, "General", 0,
                                                         (type) =>
                {
                    if (type != 0)
                    {
                        return;
                    }

                    Logger.Info($"[Developer] {JsonConvert.SerializeObject(player.Character.Style)}");
                }, "All");
            }
コード例 #14
0
            public async void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                var waypoint = World.GetWaypointBlip();

                if (waypoint == null)
                {
                    return;
                }

                var position = waypoint.Position;

                position.Z = World.GetGroundHeight(position) + 1;

                await player.Entity.Teleport(position.ToPosition());
            }
コード例 #15
0
        /// <summary>Removes a texture from the atlas.</summary>
        /// <param name="texture">The texture to remove.</param>
        public void Remove(AtlasEntity texture)
        {
            if (texture == null)
            {
                return;
            }

            AtlasLocation location = Get(texture.GetAtlasID());

            if (location == null)
            {
                return;
            }

            // Make the location available:
            location.Deselect();
        }
コード例 #16
0
        public AtlasLocation RequireImage(AtlasEntity image)
        {
            // Get the image from the global atlas stack.
            AtlasLocation location = AtlasStacks.Graphics.RequireImage(image);

            if (location == null)
            {
                // It's separate from the atlas. Too big to fit/ not worth being on an atlas.
                Isolate();
            }
            else
            {
                location.UsageCount++;
                Include();
            }

            return(location);
        }
コード例 #17
0
        /// <summary>Optimizes the atlas by removing all 'holes' (removed images) from the atlas.
        /// It reconstructs the whole atlas (only when there are actually holes), so this method should be considered expensive.
        /// This is only ever called when we fail to add something to the atlas; Theres no performace issues of a non-optimized atlas.
        /// Instead it just simply has very fragmented space available.</summary>
        public bool Optimize()
        {
            if (!CanOptimize)
            {
                // It'll do as it is.
                return(false);
            }

            // Make sure it's not called again:
            CanOptimize       = false;
            OptimizeRequested = false;

            Dictionary <int, AtlasLocation> allImages = Stack.ActiveImages;

            // Clear the textures and add in the starting empty location.
            Reset();

            // Next up, add them all back in, and that's it!
            // The optimizing comes from them trying to fit in the smallest possible gap they can when added.
            foreach (KeyValuePair <int, AtlasLocation> kvp in allImages)
            {
                AtlasLocation location = kvp.Value;

                if (location.Atlas == this)
                {
                    AtlasEntity image = location.Image;

                    int entityID = image.GetAtlasID();

                    int width;
                    int height;

                    image.GetDimensionsOnAtlas(out width, out height);

                    Add(image, entityID, width, height);
                }
            }

            return(true);
        }
コード例 #18
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 1)
                {
                    return;
                }

                var argument = arguments[0];

                foreach (var item in Items)
                {
                    if (item.Key != argument.ToLower())
                    {
                        continue;
                    }

                    ItemHelper.Give(InventoryManager.GetModule().GetContainer("pockets_inventory"),
                                    (InventoryItem)Activator.CreateInstance(item.Value));

                    Chat.SendLocalMessage("Föremål", $"Gav dig x1 utav `{item.Key}`...", Color.FromArgb(0, 255, 0));
                    break;
                }
            }
コード例 #19
0
            public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
            {
                if (arguments.Count < 1)
                {
                    Chat.SendLocalMessage("Session", $"{Session.LastSession}", Color.FromArgb(0, 0, 255));

                    return;
                }

                int id;

                try
                {
                    id = int.Parse(arguments.ElementAt(0));
                }
                catch (Exception)
                {
                    id = 0;
                }

                Session.Join(id);

                Chat.SendLocalMessage("Session", $"Anslöt till session #{id}", Color.FromArgb(0, 0, 255));
            }
コード例 #20
0
        /// <summary>This texture has selected this location to fit into. This adds it to the atlas.</summary>
        /// <param name="texture">The texture that wants to go here.</param>
        /// <param name="width">The width of the texture in pixels.</param>
        /// <param name="height">The height of the texture in pixels.</param>
        public void Select(AtlasEntity image, int width, int height, int spacing)
        {
            // The given texture wants to go in this location.
            // Width and height are given for dynamic textures - textures who's pixels are actually written straight to the atlas.
            Empty = false;

            int spacedWidth  = width + spacing;
            int spacedHeight = height + spacing;

            // Remove from empty queue:
            if (EmptyBefore == null)
            {
                Atlas.FirstEmpty = EmptyAfter;
            }
            else
            {
                EmptyBefore.EmptyAfter = EmptyAfter;
            }

            if (EmptyAfter == null)
            {
                Atlas.LastEmpty = EmptyBefore;
            }
            else
            {
                EmptyAfter.EmptyBefore = EmptyBefore;
            }

            int entityID = image.GetAtlasID();

            if (AtlasID == entityID)
            {
                // This is a restore - we don't need to do anything else.
                return;
            }

            Image   = image;
            AtlasID = entityID;
            // If it's not a perfect fit, generate new atlas locations to the right and above of this one.

            if (Atlas.Mode == AtlasingMode.SmallestSpace)
            {
                if (Width > spacedWidth)
                {
                    // The textures a little thin.

                    // Generate a new area to the right of this one (NB: 0,0 is bottom left)
                    AtlasLocation newRight = new AtlasLocation(Atlas, X + spacedWidth, Y, Width - spacedWidth, height);
                    // Immediately mark this as empty:
                    newRight.AddToEmptySet();
                }

                if (Height > spacedHeight)
                {
                    // The textures a little short.

                    // Generate a new area above this one (NB: 0,0 is bottom left)
                    AtlasLocation newTop = new AtlasLocation(Atlas, X, Y + spacedHeight, Width, Height - spacedHeight);
                    // Immediately mark this as empty:
                    newTop.AddToEmptySet();
                }
            }
            else
            {
                int maxX = X + spacedWidth;

                if (Atlas.ColumnProgress < maxX)
                {
                    Atlas.ColumnProgress = maxX;
                }

                if (Height > spacedHeight)
                {
                    // The textures a little short.

                    // Generate a new area above this one (NB: 0,0 is bottom left)
                    AtlasLocation newTop = new AtlasLocation(Atlas, X, Y + spacedHeight, Width, Height - spacedHeight);
                    // Immediately mark this as empty:
                    newTop.AddToEmptySet();
                }
            }

            // Set the new size of this location for UV baking:
            Width   = width;
            Height  = height;
            Spacing = spacing;

            // Update the UV's:
            BakeUV();

            // Make sure the area is up to date:
            Area = spacedWidth * spacedHeight;

            // Write it in:
            Flush();
        }
コード例 #21
0
//--------------------------------------
コード例 #22
0
		/// <summary>This texture has selected this location to fit into. This adds it to the atlas.</summary>
		/// <param name="texture">The texture that wants to go here.</param>
		/// <param name="width">The width of the texture in pixels.</param>
		/// <param name="height">The height of the texture in pixels.</param>
		public void Select(AtlasEntity image,int width,int height,int spacing){
			// The given texture wants to go in this location.
			// Width and height are given for dynamic textures - textures who's pixels are actually written straight to the atlas.
			Empty=false;
			
			int spacedWidth=width+spacing;
			int spacedHeight=height+spacing;
			
			// Remove from empty queue:
			if(EmptyBefore==null){
				Atlas.FirstEmpty=EmptyAfter;
			}else{
				EmptyBefore.EmptyAfter=EmptyAfter;
			}
			
			if(EmptyAfter==null){
				Atlas.LastEmpty=EmptyBefore;
			}else{
				EmptyAfter.EmptyBefore=EmptyBefore;
			}
			
			int entityID=image.GetAtlasID();
			
			if(AtlasID==entityID){
				// This is a restore - we don't need to do anything else.
				return;
			}
			
			Image=image;
			AtlasID=entityID;
			// If it's not a perfect fit, generate new atlas locations to the right and above of this one.
			
			if(Atlas.Mode==AtlasingMode.SmallestSpace){
			
				if(Width>spacedWidth){
					// The textures a little thin.
					
					// Generate a new area to the right of this one (NB: 0,0 is bottom left)
					AtlasLocation newRight=new AtlasLocation(Atlas,X+spacedWidth,Y,Width-spacedWidth,height);
					// Immediately mark this as empty:
					newRight.AddToEmptySet();
				}
				
				if(Height>spacedHeight){
					// The textures a little short.
					
					// Generate a new area above this one (NB: 0,0 is bottom left)
					AtlasLocation newTop=new AtlasLocation(Atlas,X,Y+spacedHeight,Width,Height-spacedHeight);
					// Immediately mark this as empty:
					newTop.AddToEmptySet();
				}
				
			}else{
				
				int maxX=X+spacedWidth;
				
				if(Atlas.ColumnProgress < maxX){
					
					Atlas.ColumnProgress=maxX;
					
				}
				
				if(Height>spacedHeight){
					// The textures a little short.
					
					// Generate a new area above this one (NB: 0,0 is bottom left)
					AtlasLocation newTop=new AtlasLocation(Atlas,X,Y+spacedHeight,Width,Height-spacedHeight);
					// Immediately mark this as empty:
					newTop.AddToEmptySet();
				}
				
			}
			
			// Set the new size of this location for UV baking:
			Width=width;
			Height=height;
			Spacing=spacing;
			
			// Update the UV's:
			BakeUV();
			
			// Make sure the area is up to date:
			Area=spacedWidth*spacedHeight;
			
			// Write it in:
			Flush();
		}
コード例 #23
0
        /// <summary>Require the given image on any atlas. Note that this may reject the requirement if the image is too big and isn't worthwhile on an atlas.</summary>
        public AtlasLocation RequireImage(AtlasEntity image)
        {
            int entityID = image.GetAtlasID();

            AtlasLocation result;

            if (ActiveImages.TryGetValue(entityID, out result))
            {
                // Most calls fall through here.
                return(result);
            }

            int width;
            int height;

            image.GetDimensionsOnAtlas(out width, out height);

            if (width > InitialSize || height > InitialSize)
            {
                // Won't fit or is unsuitable for atlasing anyway.
                return(null);
            }

            if (Last == null)
            {
                Create();
            }
            else
            {
                // Fast check - was this texture recently removed from any atlas?
                // We might have the chance of restoring it.
                // Their added at the back of the empty queue, so naturally, start at the end of the empty set
                // and go back until we hit one with a null texture.

                TextureAtlas currentAtlas = Last;

                while (currentAtlas != null)
                {
                    AtlasLocation currentE = currentAtlas.LastEmpty;

                    while (currentE != null)
                    {
                        if (currentE.Image == null)
                        {
                            // Nope! Shame.
                            break;
                        }
                        else if (currentE.AtlasID == entityID)
                        {
                            // Ace! Time to bring it back from the dead.
                            currentE.Select(image, width, height, Spacing);
                            ActiveImages[entityID] = currentE;

                            return(currentE);
                        }

                        currentE = currentE.EmptyBefore;
                    }

                    currentAtlas = currentAtlas.Previous;
                }
            }

            // Push to top of stack:
            result = Last.Add(image, entityID, width, height);

            if (result != null)
            {
                return(result);
            }

            // Non-fitter - try fitting in lower stack frames:

            TextureAtlas current = Last.Previous;

            while (current != null)
            {
                result = current.Add(image, entityID, width, height);

                if (result != null)
                {
                    return(result);
                }

                current = current.Previous;
            }

            // Still not fitting! Create a new stack frame:
            Create();

            return(Last.Add(image, entityID, width, height));
        }
コード例 #24
0
ファイル: RoleplayChat.cs プロジェクト: manups4e/Atlas
 public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
 {
     Chat.SendGlobalMessage(player.Character.Fullname, string.Join(" ", arguments),
                            Color.FromArgb(50, 50, 255));
 }
コード例 #25
0
		/// <summary>Require the given image on any atlas. Note that this may reject the requirement if the image is too big and isn't worthwhile on an atlas.</summary>
		public AtlasLocation RequireImage(AtlasEntity image){
			
			int entityID=image.GetAtlasID();
			
			AtlasLocation result;
			if(ActiveImages.TryGetValue(entityID,out result)){
				// Most calls fall through here.
				return result;
			}
			
			int width;
			int height;
			
			image.GetDimensionsOnAtlas(out width,out height);
			
			if(width>InitialSize || height>InitialSize){
				// Won't fit or is unsuitable for atlasing anyway.
				return null;
			}
			
			if(Last==null){
				Create();
			}else{
				
				// Fast check - was this texture recently removed from any atlas?
				// We might have the chance of restoring it.
				// Their added at the back of the empty queue, so naturally, start at the end of the empty set
				// and go back until we hit one with a null texture.
				
				TextureAtlas currentAtlas=Last;
				
				while(currentAtlas!=null){
					
					AtlasLocation currentE=currentAtlas.LastEmpty;
					
					while(currentE!=null){
						
						if(currentE.Image==null){
							// Nope! Shame.
							break;
						}else if(currentE.AtlasID==entityID){
							// Ace! Time to bring it back from the dead.
							currentE.Select(image,width,height,Spacing);
							ActiveImages[entityID]=currentE;
							
							return currentE;
						}
						
						currentE=currentE.EmptyBefore;
					}
					
					currentAtlas=currentAtlas.Previous;
				}
				
			}
			
			// Push to top of stack:
			result=Last.Add(image,entityID,width,height);
			
			if(result!=null){
				return result;
			}
			
			// Non-fitter - try fitting in lower stack frames:
			
			TextureAtlas current=Last.Previous;
			
			while(current!=null){
				
				result=current.Add(image,entityID,width,height);
				
				if(result!=null){
					return result;
				}
				
				current=current.Previous;
			}
			
			// Still not fitting! Create a new stack frame:
			Create();
			
			return Last.Add(image,entityID,width,height);
			
		}
コード例 #26
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1)
            {
                return;
            }

            if (tile != null)
            {
                _scale = tile.TileScale;
            }

            //facade texture to decorate this building
            _currentFacade =
                _options.atlasInfo.Textures[UnityEngine.Random.Range(0, _options.atlasInfo.Textures.Count)];
            //rect is a struct so we're caching this
            _currentTextureRect = _currentFacade.TextureRect;

            //this can be moved to initialize or in an if clause if you're sure all your tiles will be same level/scale
            _singleFloorHeight         = (tile.TileScale * _currentFacade.FloorHeight) / _currentFacade.MidFloorCount;
            _scaledFirstFloorHeight    = tile.TileScale * _currentFacade.FirstFloorHeight;
            _scaledTopFloorHeight      = tile.TileScale * _currentFacade.TopFloorHeight;
            _scaledPreferredWallLength = tile.TileScale * _currentFacade.PreferredEdgeSectionLength;
            _scaledFloorHeight         = _scaledPreferredWallLength * _currentFacade.WallToFloorRatio;
            _singleColumnLength        = _scaledPreferredWallLength / _currentFacade.ColumnCount;

            //read or force height
            float maxHeight = 1, minHeight = 0;

            //query height and push polygon up to create roof
            //can we do this vice versa and create roof at last?
            QueryHeight(feature, md, tile, out maxHeight, out minHeight);
            maxHeight = maxHeight * _options.extrusionScaleFactor * _scale;
            minHeight = minHeight * _options.extrusionScaleFactor * _scale;
            height    = (maxHeight - minHeight);

            //we cann GenerateRoofMesh even if extrusion type is sidewall-only
            //it pushes the vertices to building height, then we clear top polygon triangles
            //to remove roof.
            GenerateRoofMesh(md, minHeight, maxHeight);
            if (_options.extrusionGeometryType == ExtrusionGeometryType.SideOnly)
            {
                md.Triangles[0].Clear();
            }

            if (_options.extrusionGeometryType != ExtrusionGeometryType.RoofOnly)
            {
                //limiting section heights, first floor gets priority, then we draw top floor, then mid if we still have space
                finalFirstHeight = Mathf.Min(height, _scaledFirstFloorHeight);
                finalTopHeight   = (height - finalFirstHeight) < _scaledTopFloorHeight ? 0 : _scaledTopFloorHeight;
                finalMidHeight   = Mathf.Max(0, height - (finalFirstHeight + finalTopHeight));
                wallTriangles    = new List <int>();

                //cuts long edges into smaller ones using PreferredEdgeSectionLength
                currentWallLength    = 0;
                start                = Constants.Math.Vector3Zero;
                wallSegmentDirection = Constants.Math.Vector3Zero;

                finalLeftOverRowHeight = 0f;
                if (finalMidHeight > 0)
                {
                    finalLeftOverRowHeight = finalMidHeight;
                    finalLeftOverRowHeight = finalLeftOverRowHeight % _singleFloorHeight;
                    finalMidHeight        -= finalLeftOverRowHeight;
                }
                else
                {
                    finalLeftOverRowHeight = finalTopHeight;
                }

                for (int i = 0; i < md.Edges.Count; i += 2)
                {
                    var v1 = md.Vertices[md.Edges[i]];
                    var v2 = md.Vertices[md.Edges[i + 1]];

                    wallDirection = v2 - v1;

                    currentWallLength     = Vector3.Distance(v1, v2);
                    _leftOverColumnLength = currentWallLength % _singleColumnLength;
                    start = v1;
                    wallSegmentDirection = (v2 - v1).normalized;

                    //half of leftover column (if _centerSegments ofc) at the begining
                    if (_centerSegments && currentWallLength > _singleColumnLength)
                    {
                        //save left,right vertices and wall length
                        wallSegmentFirstVertex = start;
                        wallSegmentLength      = (_leftOverColumnLength / 2);
                        start += wallSegmentDirection * wallSegmentLength;
                        wallSegmentSecondVertex = start;

                        _leftOverColumnLength = _leftOverColumnLength / 2;
                        CreateWall(md);
                    }

                    while (currentWallLength > _singleColumnLength)
                    {
                        wallSegmentFirstVertex = start;
                        //columns fitting wall / max column we have in texture
                        var stepRatio =
                            (float)Math.Min(_currentFacade.ColumnCount,
                                            Math.Floor(currentWallLength / _singleColumnLength)) / _currentFacade.ColumnCount;
                        wallSegmentLength       = stepRatio * _scaledPreferredWallLength;
                        start                  += wallSegmentDirection * wallSegmentLength;
                        wallSegmentSecondVertex = start;

                        currentWallLength -= (stepRatio * _scaledPreferredWallLength);
                        CreateWall(md);
                    }

                    //left over column at the end
                    if (_leftOverColumnLength > 0)
                    {
                        wallSegmentFirstVertex  = start;
                        wallSegmentSecondVertex = v2;
                        wallSegmentLength       = _leftOverColumnLength;
                        CreateWall(md);
                    }
                }

                //this first loop is for columns
                if (_separateSubmesh)
                {
                    md.Triangles.Add(wallTriangles);
                }
                else
                {
                    md.Triangles.Capacity = md.Triangles.Count + wallTriangles.Count;
                    md.Triangles[0].AddRange(wallTriangles);
                }
            }
        }
コード例 #27
0
		/// <summary>Adds the given texture to the atlas if it's not already on it,
		/// taking up a set amount of space on the atlas.</summary>
		/// <param name="texture">The texture to add.</param>
		/// <param name="width">The x amount of space to take up on the atlas.</param>
		/// <param name="height">The y amount of space to take up on the atlas.</param>
		/// <returns>The location of the texture on the atlas.</returns>
		internal AtlasLocation Add(AtlasEntity texture,int entityID,int width,int height){
			
			// Pad width/height:
			int spacedWidth=width+RawSpacing;
			int spacedHeight=height+RawSpacing;
			
			// Look for a spot to park this texture in the set of empty blocks.
			
			// The aim is to make it fit in the smallest empty block possible to save space.
			// This is done with a 'fitFactor' - this is simply the difference between the blocks area and the textures area.
			// We want this value to be as small as possible.
			int fitFactor=0;
			AtlasLocation currentAccepted=null;
			
			int area=spacedWidth*spacedHeight;
			
			AtlasLocation currentEmpty=FirstEmpty;
			
			while(currentEmpty!=null){
				int factor=currentEmpty.FitFactor(spacedWidth,spacedHeight,area);
				
				if(factor==0){
					// Perfect fit - break right now; can't beat that!
					currentAccepted=currentEmpty;
					break;
					
				}else if(factor!=-1){
					// We can possibly fit here - is it the current smallest?
					if(currentAccepted==null||factor<fitFactor){
						// Yep! select it.
						fitFactor=factor;
						currentAccepted=currentEmpty;
					}
				}
				
				currentEmpty=currentEmpty.EmptyAfter;
			}
			
			if(Mode==AtlasingMode.Columns && currentAccepted==null){
				
				// Is there any more column space?
				int max=ColumnProgress + spacedWidth;
				
				if(max<=Dimension){
					
					// Yep! Create a location using the remaining space:
					currentAccepted=new AtlasLocation(this,ColumnProgress,0,Dimension-ColumnProgress,Dimension);
					
					// As it's a new location, it's empty by default:
					// (Note that it must be in the empty set, otherwise Select will throw the empty set entirely)
					currentAccepted.AddToEmptySet();
					
				}
				
			}
			
			if(currentAccepted==null){
				// No space in this atlas to fit it in. Stop there.
				
				if(CanOptimize){
					// Request an optimise:
					OptimizeRequested=true;
					Stack.OptimizeRequested=true;
				}
				
				return null;
			}
			
			Stack.ActiveImages[entityID]=currentAccepted;
			
			// And burn in the texture to the location (nb: it internally also writes the pixels to the atlas).
			currentAccepted.Select(texture,width,height,RawSpacing);
			
			return currentAccepted;
		}
コード例 #28
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (Criteria != null && Criteria.Count > 0)
            {
                foreach (var criterion in Criteria)
                {
                    if (criterion.ShouldReplaceFeature(feature))
                    {
                        return;
                    }
                }
            }

            var            _counter = feature.Points.Count;
            var            subset = new List <List <Vector3> >(_counter);
            Data           flatData = null;
            List <int>     result = null;
            var            currentIndex = 0;
            int            vertCount = 0, polygonVertexCount = 0;
            List <int>     triList = null;
            List <Vector3> sub     = null;



            for (int i = 0; i < _counter; i++)
            {
                sub = feature.Points[i];
                //earcut is built to handle one polygon with multiple holes
                //point data can contain multiple polygons though, so we're handling them separately here

                vertCount = md.Vertices.Count;
                if (IsClockwise(sub) && vertCount > 0)
                {
                    flatData           = EarcutLibrary.Flatten(subset);
                    result             = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
                    polygonVertexCount = result.Count;
                    if (triList == null)
                    {
                        triList = new List <int>(polygonVertexCount);
                    }
                    else
                    {
                        triList.Capacity = triList.Count + polygonVertexCount;
                    }

                    for (int j = 0; j < polygonVertexCount; j++)
                    {
                        triList.Add(result[j] + currentIndex);
                    }

                    currentIndex = vertCount;
                    subset.Clear();
                }

                subset.Add(sub);

                polygonVertexCount   = sub.Count;
                md.Vertices.Capacity = md.Vertices.Count + polygonVertexCount;
                md.Normals.Capacity  = md.Normals.Count + polygonVertexCount;
                md.Edges.Capacity    = md.Edges.Count + polygonVertexCount * 2;
                var _size = md.TileRect.Size;

                for (int j = 0; j < polygonVertexCount; j++)
                {
                    md.Edges.Add(vertCount + ((j + 1) % polygonVertexCount));
                    md.Edges.Add(vertCount + j);
                    md.Vertices.Add(sub[j]);
                    md.Tangents.Add(Constants.Math.Vector3Forward);
                    md.Normals.Add(Constants.Math.Vector3Up);

                    if (_options.style == StyleTypes.Satellite)
                    {
                        var fromBottomLeft = new Vector2(
                            (float)(((sub[j].x + md.PositionInTile.x) / tile.TileScale + _size.x / 2) / _size.x),
                            (float)(((sub[j].z + md.PositionInTile.z) / tile.TileScale + _size.x / 2) / _size.x));
                        md.UV[0].Add(fromBottomLeft);
                    }
                    else if (_options.texturingType == UvMapType.Tiled)
                    {
                        md.UV[0].Add(new Vector2(sub[j].x, sub[j].z));
                    }
                }
            }

            flatData           = EarcutLibrary.Flatten(subset);
            result             = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
            polygonVertexCount = result.Count;

            if (_options.texturingType == UvMapType.Atlas || _options.texturingType == UvMapType.AtlasWithColorPalette)
            {
                _currentFacade = _options.atlasInfo.Roofs[UnityEngine.Random.Range(0, _options.atlasInfo.Roofs.Count)];

                minx = float.MaxValue;
                miny = float.MaxValue;
                maxx = float.MinValue;
                maxy = float.MinValue;

                _textureUvCoordinates    = new Vector2[md.Vertices.Count];
                _textureDirection        = Quaternion.FromToRotation((md.Vertices[0] - md.Vertices[1]), Mapbox.Unity.Constants.Math.Vector3Right);
                _textureUvCoordinates[0] = new Vector2(0, 0);
                _firstVert = md.Vertices[0];
                for (int i = 1; i < md.Vertices.Count; i++)
                {
                    _vert = md.Vertices[i];
                    _vertexRelativePos       = _vert - _firstVert;
                    _vertexRelativePos       = _textureDirection * _vertexRelativePos;
                    _textureUvCoordinates[i] = new Vector2(_vertexRelativePos.x, _vertexRelativePos.z);
                    if (_vertexRelativePos.x < minx)
                    {
                        minx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.x > maxx)
                    {
                        maxx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.z < miny)
                    {
                        miny = _vertexRelativePos.z;
                    }
                    if (_vertexRelativePos.z > maxy)
                    {
                        maxy = _vertexRelativePos.z;
                    }
                }

                var width  = maxx - minx;
                var height = maxy - miny;

                for (int i = 0; i < md.Vertices.Count; i++)
                {
                    md.UV[0].Add(new Vector2(
                                     (((_textureUvCoordinates[i].x - minx) / width) * _currentFacade.TextureRect.width) + _currentFacade.TextureRect.x,
                                     (((_textureUvCoordinates[i].y - miny) / height) * _currentFacade.TextureRect.height) + _currentFacade.TextureRect.y));
                }
            }

            if (triList == null)
            {
                triList = new List <int>(polygonVertexCount);
            }
            else
            {
                triList.Capacity = triList.Count + polygonVertexCount;
            }

            for (int i = 0; i < polygonVertexCount; i++)
            {
                triList.Add(result[i] + currentIndex);
            }

            md.Triangles.Add(triList);
        }
コード例 #29
0
        private void DrawAtlasEntityData(List <AtlasEntity> aeList)
        {
            for (int i = 0; i < aeList.Count; i++)
            {
                AtlasEntity ae = aeList[i];

                Rect baseRect = ae.TextureRect;

                float topRatio    = ae.TopSectionRatio * baseRect.height;
                float bottomRatio = ae.BottomSectionRatio * baseRect.height;
                float middleRatio = baseRect.height - (topRatio + bottomRatio);

                Rect groundFloorRect = new Rect(baseRect.x, baseRect.y, baseRect.width, bottomRatio);
                Rect topFloorRect    = new Rect(baseRect.x, baseRect.y + baseRect.height - topRatio, baseRect.width, topRatio);

                PixelRect basePixelRect        = ConvertUVRectToPixelRect(baseRect);
                PixelRect groundFloorPixelRect = ConvertUVRectToPixelRect(groundFloorRect);
                PixelRect topFloorPixelRect    = ConvertUVRectToPixelRect(topFloorRect);

                Color color      = m_colors[_drawCount];
                Color colorLight = (color + Color.white) / 2;
                Color colorDark  = (color + Color.black) / 2;

                DrawRect(basePixelRect, color);
                DrawRect(groundFloorPixelRect, colorLight);
                DrawRect(topFloorPixelRect, colorDark);

                DrawDebugCross(groundFloorPixelRect);
                DrawDebugCross(topFloorPixelRect);

                int numColumns   = (int)ae.ColumnCount;
                int numMidFloors = ae.MidFloorCount;

                float colWidth    = baseRect.width / numColumns;
                float floorHeight = middleRatio / numMidFloors;

                float midFloorBase = baseRect.y + bottomRatio;

                float mrgn     = _cellRatioMargin;
                float halfMrgn = mrgn / 2;

                for (int j = 0; j < numMidFloors; j++)
                {
                    float floorStart = midFloorBase + (floorHeight * j);

                    for (int k = 0; k < numColumns; k++)
                    {
                        float columnStart = baseRect.x + (colWidth * k);

                        Rect      cellRect      = new Rect(columnStart + halfMrgn, floorStart + halfMrgn, colWidth - mrgn, floorHeight - mrgn);
                        PixelRect cellPixelRect = ConvertUVRectToPixelRect(cellRect);

                        DrawRect(cellPixelRect, Color.white);
                        DrawDebugCross(cellPixelRect);
                    }
                }
                DrawCornerWatermarks(groundFloorPixelRect);
                DrawCornerWatermarks(topFloorPixelRect);
                _drawCount++;
            }
        }
コード例 #30
0
 public void On(AtlasPlayer player, AtlasEntity entity, List <string> arguments)
 {
     entity.Vehicle?.Delete();
 }
コード例 #31
0
        public override void Run(CustomFeatureUnity feature, ref MeshDataStruct md)
        {
            var counter = feature.Points.Count;
            var subset  = new List <List <Vector3> >(counter);

            Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers.Data flatData;
            List <int>       result;
            var              currentIndex       = 0;
            var              polygonVertexCount = 0;
            NativeList <int> triList            = default;

            for (var i = 0; i < counter; i++)
            {
                var sub = feature.Points[i];
                // ear cut is built to handle one polygon with multiple holes
                //point data can contain multiple polygons though, so we're handling them separately here

                var vertCount = md.Vertices.Length;
                if (IsClockwise(sub) && vertCount > 0)
                {
                    flatData           = Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers.EarcutLibrary.Flatten(subset);
                    result             = Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers.EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
                    polygonVertexCount = result.Count;

                    if (!triList.IsCreated)
                    {
                        triList = new NativeList <int>(polygonVertexCount, Allocator.TempJob);
                    }
                    else
                    {
                        triList.Capacity = triList.Length + polygonVertexCount;
                    }

                    for (var j = 0; j < polygonVertexCount; j++)
                    {
                        triList.Add(result[j] + currentIndex);
                    }

                    currentIndex = vertCount;
                    subset.Clear();
                }

                subset.Add(sub);

                polygonVertexCount   = sub.Count;
                md.Vertices.Capacity = md.Vertices.Length + polygonVertexCount;
                md.Normals.Capacity  = md.Normals.Length + polygonVertexCount;
                md.Edges.Capacity    = md.Edges.Length + polygonVertexCount * 2;

                for (var j = 0; j < polygonVertexCount; j++)
                {
                    md.Edges.Add(vertCount + ((j + 1) % polygonVertexCount));
                    md.Edges.Add(vertCount + j);
                    md.Vertices.Add(sub[j]);
                    md.Normals.Add(Vector3.up);
                    if (_options.texturingType != UvMapType.Tiled)
                    {
                        continue;
                    }
                    md.UV.Add(new Vector2(sub[j].x, sub[j].z));
                }
            }

            flatData           = Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers.EarcutLibrary.Flatten(subset);
            result             = Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers.EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
            polygonVertexCount = result.Count;

            if (_options.texturingType == UvMapType.Atlas || _options.texturingType == UvMapType.AtlasWithColorPalette)
            {
                _currentFacade = _options.atlasInfo.Roofs[UnityEngine.Random.Range(0, _options.atlasInfo.Roofs.Count)];

                var minx = float.MaxValue;
                var miny = float.MaxValue;
                var maxx = float.MinValue;
                var maxy = float.MinValue;

                var textureUvCoordinates = new Vector2[md.Vertices.Length];
                var textureDirection     = Quaternion.FromToRotation(md.Vertices[0] - md.Vertices[1], Vector3.right);
                textureUvCoordinates[0] = new Vector2(0, 0);

                for (var i = 1; i < md.Vertices.Length; i++)
                {
                    var vert = md.Vertices[i];
                    var vertexRelativePos = textureDirection * (vert - md.Vertices[0]);
                    textureUvCoordinates[i] = new Vector2(vertexRelativePos.x, vertexRelativePos.z);
                    if (vertexRelativePos.x < minx)
                    {
                        minx = vertexRelativePos.x;
                    }
                    if (vertexRelativePos.x > maxx)
                    {
                        maxx = vertexRelativePos.x;
                    }
                    if (vertexRelativePos.z < miny)
                    {
                        miny = vertexRelativePos.z;
                    }
                    if (vertexRelativePos.z > maxy)
                    {
                        maxy = vertexRelativePos.z;
                    }
                }

                var width  = maxx - minx;
                var height = maxy - miny;

                for (var i = 0; i < md.Vertices.Length; i++)
                {
                    md.UV.Add(new Vector2(
                                  (((textureUvCoordinates[i].x - minx) / width) * _currentFacade.TextureRect.width) + _currentFacade.TextureRect.x,
                                  (((textureUvCoordinates[i].y - miny) / height) * _currentFacade.TextureRect.height) + _currentFacade.TextureRect.y));
                }
            }

            if (!triList.IsCreated)
            {
                triList = new NativeList <int>(polygonVertexCount, Allocator.TempJob);
            }
            else
            {
                triList.Capacity = triList.Length + polygonVertexCount;
            }

            for (var i = 0; i < polygonVertexCount; i++)
            {
                triList.Add(result[i] + currentIndex);
            }
            md.Triangles.AddRange(triList);

            triList.Dispose();
        }
コード例 #32
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            _uv.Clear();
            _mdVertexCount = md.Vertices.Count;
            _size          = md.TileRect.Size;

            if (_options.texturingType != UvMapType.Atlas && _options.texturingType != UvMapType.AtlasWithColorPalette)
            {
                for (int i = 0; i < _mdVertexCount; i++)
                {
                    _vert = md.Vertices[i];
                    if (_options.texturingType == UvMapType.Tiled)
                    {
                        _uv.Add(new Vector2(_vert.x, _vert.z));
                    }
                    else if (_options.texturingType == UvMapType.Satellite)
                    {
                        var fromBottomLeft = new Vector2((float)(((_vert.x + md.PositionInTile.x) / tile.TileScale + _size.x / 2) / _size.x),
                                                         (float)(((_vert.z + md.PositionInTile.z) / tile.TileScale + _size.x / 2) / _size.x));
                        _uv.Add(fromBottomLeft);
                    }
                }
            }
            else if (_options.texturingType == UvMapType.Atlas || _options.texturingType == UvMapType.AtlasWithColorPalette)
            {
                _currentFacade = _options.atlasInfo.Roofs[UnityEngine.Random.Range(0, _options.atlasInfo.Roofs.Count)];

                float minx = float.MaxValue, miny = float.MaxValue, maxx = float.MinValue, maxy = float.MinValue;
                _textureUvCoordinates    = new Vector2[_mdVertexCount];
                _textureDirection        = Quaternion.FromToRotation((md.Vertices[_mdVertexCount - 2] - md.Vertices[0]), Mapbox.Unity.Constants.Math.Vector3Right);
                _textureUvCoordinates[0] = new Vector2(0, 0);
                _firstVert = md.Vertices[0];
                for (int i = 1; i < _mdVertexCount; i++)
                {
                    _vert = md.Vertices[i];
                    _vertexRelativePos       = _vert - _firstVert;
                    _vertexRelativePos       = _textureDirection * _vertexRelativePos;
                    _textureUvCoordinates[i] = new Vector2(_vertexRelativePos.x, _vertexRelativePos.z);
                    if (_vertexRelativePos.x < minx)
                    {
                        minx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.x > maxx)
                    {
                        maxx = _vertexRelativePos.x;
                    }
                    if (_vertexRelativePos.z < miny)
                    {
                        miny = _vertexRelativePos.z;
                    }
                    if (_vertexRelativePos.z > maxy)
                    {
                        maxy = _vertexRelativePos.z;
                    }
                }

                var width  = maxx - minx;
                var height = maxy - minx;

                for (int i = 0; i < _mdVertexCount; i++)
                {
                    //var nx = _textureUvCoordinates[i].x - minx; //first point isn't always the min
                    //var ny = _textureUvCoordinates[i].y - miny;
                    //var xx = (nx / (maxx - minx)) * _currentFacade.TextureRect.width + _currentFacade.TextureRect.x;
                    //var yy = (ny / (maxy - miny)) * _currentFacade.TextureRect.height + _currentFacade.TextureRect.y;
                    _uv.Add(new Vector2(
                                (((_textureUvCoordinates[i].x - minx) / width) * _currentFacade.TextureRect.width) + _currentFacade.TextureRect.x,
                                (((_textureUvCoordinates[i].y - miny) / height) * _currentFacade.TextureRect.height) + _currentFacade.TextureRect.y));
                }
            }

            md.UV[0].AddRange(_uv);
        }
コード例 #33
0
        /// <summary>Adds the given texture to the atlas if it's not already on it,
        /// taking up a set amount of space on the atlas.</summary>
        /// <param name="texture">The texture to add.</param>
        /// <param name="width">The x amount of space to take up on the atlas.</param>
        /// <param name="height">The y amount of space to take up on the atlas.</param>
        /// <returns>The location of the texture on the atlas.</returns>
        internal AtlasLocation Add(AtlasEntity texture, int entityID, int width, int height)
        {
            // Pad width/height:
            int spacedWidth  = width + RawSpacing;
            int spacedHeight = height + RawSpacing;

            // Look for a spot to park this texture in the set of empty blocks.

            // The aim is to make it fit in the smallest empty block possible to save space.
            // This is done with a 'fitFactor' - this is simply the difference between the blocks area and the textures area.
            // We want this value to be as small as possible.
            AtlasLocation currentAccepted = null;

            int area = spacedWidth * spacedHeight;

            if (Mode == AtlasingMode.Columns)
            {
                // Space in this column?
                int max = ColumnProgressY + spacedHeight;

                if (max <= Dimension)
                {
                    // Yep! Create a location here:
                    currentAccepted = new AtlasLocation(this, ColumnProgressX, ColumnProgressY, spacedWidth, spacedHeight);

                    // Move it:
                    ColumnProgressY += spacedHeight;

                    if (spacedWidth > ColumnWidth)
                    {
                        // Update width:
                        ColumnWidth = spacedWidth;
                    }

                    // As it's a new location, it's empty by default:
                    // (Note that it must be in the empty set, otherwise Select will throw the empty set entirely)
                    currentAccepted.AddToEmptySet();
                }
                else
                {
                    // Space to generate a new column?
                    max = ColumnProgressX + ColumnWidth + spacedWidth;

                    if (max <= Dimension)
                    {
                        // Set Y:
                        ColumnProgressY = spacedHeight;

                        // Move X:
                        ColumnProgressX += ColumnWidth;

                        // Yep! Create a location here:
                        currentAccepted = new AtlasLocation(this, ColumnProgressX, 0, spacedWidth, spacedHeight);

                        // Reset width:
                        ColumnWidth = spacedWidth;

                        // As it's a new location, it's empty by default:
                        // (Note that it must be in the empty set, otherwise Select will throw the empty set entirely)
                        currentAccepted.AddToEmptySet();
                    }

                    // Otherwise, the atlas is practically full.
                    // We're gonna just reject the add (by falling below), and state that it can be optimised.
                    // This triggers another atlas to get created and this one will
                    // be optimised at some point in the near future.
                }
            }
            else
            {
                int fitFactor = 0;

                AtlasLocation currentEmpty = FirstEmpty;

                while (currentEmpty != null)
                {
                    int factor = currentEmpty.FitFactor(spacedWidth, spacedHeight, area);

                    if (factor == 0)
                    {
                        // Perfect fit - break right now; can't beat that!
                        currentAccepted = currentEmpty;
                        break;
                    }
                    else if (factor != -1)
                    {
                        // We can possibly fit here - is it the current smallest?
                        if (currentAccepted == null || factor < fitFactor)
                        {
                            // Yep! select it.
                            fitFactor       = factor;
                            currentAccepted = currentEmpty;
                        }
                    }

                    currentEmpty = currentEmpty.EmptyAfter;
                }
            }

            if (currentAccepted == null)
            {
                // No space in this atlas to fit it in. Stop there.

                if (CanOptimize)
                {
                    // Request an optimise:
                    OptimizeRequested       = true;
                    Stack.OptimizeRequested = true;
                }

                return(null);
            }

            Stack.ActiveImages[entityID] = currentAccepted;

            // And burn in the texture to the location (nb: it internally also writes the pixels to the atlas).
            currentAccepted.Select(texture, width, height, RawSpacing);

            return(currentAccepted);
        }
コード例 #34
0
        public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
        {
            if (md.Vertices.Count == 0 || feature == null || feature.Points.Count < 1)
            {
                return;
            }

            if (tile != null)
            {
                _scale = tile.TileScale;
            }

            _currentFacade = _options.atlasInfo.Textures[UnityEngine.Random.Range(0, _options.atlasInfo.Textures.Count)];
            //rect is a struct so we're caching this
            _currentTextureRect = _currentFacade.TextureRect;

            //this can be moved to initialize or in an if clause if you're sure all your tiles will be same level/scale
            _scaledFloorHeight      = tile.TileScale * _currentFacade.FloorHeight;
            _scaledFirstFloorHeight = tile.TileScale * _currentFacade.FirstFloorHeight;
            _scaledTopFloorHeight   = tile.TileScale * _currentFacade.TopFloorHeight;

            //read or force height
            float maxHeight = 1, minHeight = 0;

            QueryHeight(feature, md, tile, out maxHeight, out minHeight);
            maxHeight = maxHeight * _options.extrusionScaleFactor * _scale;
            minHeight = minHeight * _options.extrusionScaleFactor * _scale;
            height    = (maxHeight - minHeight);

            GenerateRoofMesh(md, minHeight, maxHeight);

            if (_options.extrusionGeometryType != ExtrusionGeometryType.RoofOnly)
            {
                edgeList.Clear();
                //cuts long edges into smaller ones using PreferredEdgeSectionLength
                CalculateEdgeList(md, tile, _currentFacade.PreferredEdgeSectionLength);

                //limiting section heights, first floor gets priority, then we draw top floor, then mid if we still have space
                firstHeight = Mathf.Min(height, _scaledFirstFloorHeight);
                topHeight   = Mathf.Min(height - firstHeight, _scaledTopFloorHeight);
                midHeight   = Mathf.Max(0, height - (firstHeight + topHeight));

                //we're merging small mid sections to top and small top sections to first floor to avoid really short/compressed floors
                //I think we need this but I'm not sure about implementation. I feel like mid height should be shared by top&bottom for example.
                if (midHeight < _scaledFloorHeight / (_currentFacade.MidFloorCount * 2))
                {
                    topHeight             += midHeight;
                    _scaledTopFloorHeight += midHeight;
                    midHeight              = 0;
                }
                if (topHeight < _scaledTopFloorHeight * 0.66f)                 //0.66 here is just a random number for acceptable stretching
                {
                    firstHeight += topHeight;
                    topHeight    = 0;
                }

                floorCount        = (int)(midHeight / _scaledFloorHeight) + 1;
                scaledFloorHeight = midHeight / floorCount;
                wallTriangles     = new List <int>();

                //this first loop is for columns
                for (int i = 0; i < edgeList.Count - 1; i += 2)
                {
                    v1            = edgeList[i];
                    v2            = edgeList[i + 1];
                    ind           = md.Vertices.Count;
                    wallDirection = (v2 - v1);
                    d             = wallDirection.magnitude;

                    //this part minimizes stretching for narrow columns
                    //if texture has 3 columns, 33% (of preferred edge length) wide walls will get 1 window.
                    //0-33% gets 1 window, 33-66 gets 2, 66-100 gets all three
                    //we're not wrapping/repeating texture as it won't work with atlases
                    columnScaleRatio = Math.Min(1, d / (_currentFacade.PreferredEdgeSectionLength * tile.TileScale));
                    rightOfEdgeUv    = _currentTextureRect.xMin + _currentTextureRect.size.x * Math.Min(1, ((float)(Math.Floor(columnScaleRatio * _currentFacade.ColumnCount) + 1) / _currentFacade.ColumnCount));
                    bottomOfTopUv    = _currentTextureRect.yMax - (_currentTextureRect.size.y * _currentFacade.TopSectionRatio);                  //not doing that scaling thing for y axis and floors yet
                    topOfBottomUv    = _currentTextureRect.yMin + (_currentTextureRect.size.y * _currentFacade.BottomSectionRatio);               // * (Mathf.Max(1, (float)Math.Floor(tby * textureSection.TopSectionFloorCount)) / textureSection.TopSectionFloorCount);

                    wallNormal = new Vector3(-(v1.z - v2.z), 0, (v1.x - v2.x)).normalized;
                    currentY1  = v1.y;
                    currentY2  = v2.y;

                    floorScaleRatio = Math.Min(1, midHeight / _scaledFloorHeight);
                    var midSecHeight    = (_currentTextureRect.height * (1 - _currentFacade.TopSectionRatio - _currentFacade.BottomSectionRatio));
                    var midFittedHeight = midSecHeight * Math.Min(1, ((float)(Math.Floor(floorScaleRatio * _currentFacade.MidFloorCount) + 1) / _currentFacade.MidFloorCount));                     // midHeight < _scaledFloorHeight * 0.66 ? 0.5f : 0.125f;
                    bottomOfMidUv = (_currentTextureRect.yMax - (_currentTextureRect.height * _currentFacade.TopSectionRatio)) - midFittedHeight;
                    topOfMidUv    = _currentTextureRect.yMax - (_currentTextureRect.height * _currentFacade.TopSectionRatio);

                    TopFloor(md);
                    MidFloors(md);
                    FirstFloor(md, height);
                }

                if (_separateSubmesh)
                {
                    md.Triangles.Add(wallTriangles);
                }
                else
                {
                    md.Triangles.Capacity = md.Triangles.Count + wallTriangles.Count;
                    md.Triangles[0].AddRange(wallTriangles);
                }
            }
        }
コード例 #35
0
		/// <summary>Removes a texture from the atlas.</summary>
		/// <param name="texture">The texture to remove.</param>
		public void Remove(AtlasEntity texture){
			if(texture==null){
				return;
			}
			
			AtlasLocation location=Get(texture.GetAtlasID());
			
			if(location==null){
				return;
			}
			
			// Make the location available:
			location.Deselect();
		}