How to create Unity3d gaussian plume resembling breathing puffs - c#

I'm working on a project that needs a breath effect such that it emits puffs of droplets for visualization. The puffs need to occur about 10-20 times per minute and look like water vapor expelled during cold weather. I've created several particle generators in Unity that use a cone shaped emitter and tried to adjust it to get something similar to a gaussian plume, but all I get are "rings" and I can't get one generator to create short "puffs". I finally have created 3 generators pithing the same "cone", one emits small particles, one medium sized, and the other large, but it does not resemble a collection of particles that change size after being breathed out, i.e. shrinking due to evaporation, slowing down to terminal velocities appropriate to their changing size, drifting upward due to the thermal gradient in the room, etc. Can someone point me to the documentation that explains how to create a particle generator that would provide for spatially distributed, velocity distributed, size distributed particles where the "puff" could be characterized by vz_avg, vz_sigma, vx_avg = vy_avg, vx_sigma = vy_sigma, and be able to have each particle's speed and acceleration a function of it's size, temperature difference between it and background, evaporation due to humidity and temp, etc?
The Unity engine is good at allowing one to put an avatar into a scene, move and control it representing almost realistic looking behavior, BUT, my difficulty is combining video effects in a manner that is physically realistic, i.e. gravity, buoyancy, evaporation, slowing down, etc.
Pointers appreciated.

I managed to get a series of parameters put together that allowed me to perform this task. I had to use three different emitters, one for large droplets, one for mid range droplets, and one for aerosols. Each used a different setting for gravity to emulate falling, hovering, and rising particles, restpectively. By matching the rate of emission of the "puffs" to the human breathing, the number of particles to approximate the number of viral droplets of the different sizes that have been determined to be in a breath, I was able to create a realistic "looking" cloud of particles that are emitted, drift to the floor, hover, and also rise towards the ceiling.
I just thought I'd post and answer so that others might know that it can be done, but takes a lot of working backwards from the actual physics to the way that Unity displays things to get something realistic.

Related

Translate Unity units of measurement?

In Unity one can use Raycasting to calculate various measurements. Examples such as diameter, thickness of a wall, and width. One way to do this is by capturing a users mouse click on an object and using RaycastHits to capture the location of the mouse click on the object and than casting additional rays depending on the measurement desired.
Seen below:
Thickness of the walls clicked is .0098, .0096, and .0072. Width is .0615, .0611, and .060. Diameter is .0475.
Though these measurements are (believed to be) executed and calculated correctly it's unclear how the results translate to real world units of measurement.
This is best demonstrated and shown in the fourth image. Checking the same diameter in other CAD programs, such as NX, the diameter is 0.4210" or inches. Thickness and width were calculated as well at .075244" and .252872" respectively.
So than, how do the results in Unity, (results produced using Vector3.Distance to calculate the distance between two points) translate to real world units of measurement?
Googling the subject yields a common answer: Unity's measurements are "game units" and can be used however desired. While I grasp this, I don't understand how to accomplish the translation of "game units", or whatever Unity's units of measurement truly are, to the measurement results I can see in CAD programs.
Results (CAD x Unity):
Thickness: .075244" x .0098, .0096, and .0072.
Width: .252872" x .0615, .0611, and .060.
Diameter: 0.4210" x .0475
(note1: model scales are identical in Unity and external CAD program.)
(note2: the slight variation in thickness and width results from Unity measurements coming at angles where the CAD program is measuring distance between the two planes, i.e. .009x and .06x.)
(note3: ignore the incorrect labeling of Width in the second visual as 'Thickness' and the inch labeling in all of the Unity visuals, ", as both incorrect).
1 Unity unit is generally held to be 1 meter, however as you've read it's up to your implementation, in this case it looks like you're actually exporting from CAD with 1 inch = 1 unit, since your results seem similar but slightly off.
The reason you're getting innaccuracies is most likely due to Unity's collision system not being extremely accurate, most colliders are in fact slightly larger than the mesh they represent which will throw off your fine tuned measurements significantly, and on top of that Unity will have much lower precision than CAD, since Unity is a game engine and needs to perform in realtime, 3D position data is not very accurate (it gets pretty hazy around 4 digits of precision), and in fact gets significantly worse as you travel away from the origin.
I wouldn't recommend trying to use Unity for any kind of precise design work, especially when representing the real world, but if you're dead set, you might want to scale your objects up by a factor of 10 or 100 in order to keep your digits closer to the decimal point to reduce floating point error, this is a hack obviously.
You may want to also look at your physics settings: https://docs.unity3d.com/Manual/class-PhysicsManager.html
In particular "Default Contact Offset" may be relevant (although I'm not sure if it affects raycasts)
PS: I'd post this as a comment but the rep system won't let me, your description of the measurements between each environment is really confusing, next time maybe try and format it in a table or something?

Simulate depressurization in a discrete room

I am trying to build a top down view spaceship game which has destructible parts. I need to simulate the process of depressurization in case of hull breach.
I have a tiled map which has the room partitioning code setup:
What I am trying to do is build some kind of a vector field which would determine the ways the air leaves depressurized room. So in case you would break the tile connecting the vacuum and the room (adjacent to both purple and green rooms), you'd end up with a vector map like this:
My idea is to implement some kind of scalar field (kind of similar to a potential field) to help determine the airflow (basically fill the grid with euclidean distances (taking obstacles into account) to a known zero-potential point and then calculate the vectors by taking into account all of the adjacent tiles with lower potential value that the current tile has:
However this method has a flaw to where the amount of force applied to a body in a certain point doesn't really take airflow bottlenecks and distance into account, so the force whould be the same in the tile next to vacuum tile as well as on the opposite end of the room.
Is there a better way to simulate such behavior or maybe a change to the algorithm I though of that would more or less realistically take distance and bottlenecks into account?
Algorithm upgrade ideas collected from comments:
(...) you want a realistic feeling of the "force" in this context, then it should be not based just on the distance, but rather, like you said, the airflow. You'd need to estimate it to some degree and note that it behaves similar to Kirchoff rule in electronics. Let's say the hole is small - then amount-of-air-sucked-per-second is small. The first nearest tile(s) must cover it, they lose X air per second. Their surrounding tiles also must conver it - they lose X air per second in total. And their neighbours.. and so on. That it works like Dijkstra distance but counting down.
Example: Assuming no walls, start with 16/sec at point-zero directing to hole in the ground, surrounding 8 tiles will get 2/sec directed to the point-zero tile. next layer of surrounding 12 tiles will get something like 1.33/sec and so on. Now alter that to i.e. (1) account for various initial hole sizes (2) various large no-pass-through obstacles (3) limitations in air flow due to small passages - which behave like new start points.
Another example (from the map in question): The tile that has a value of zero would have a value of, say, 1000 units/s. the ones below it would be 500/s each, the next one would be a 1000/s as well, the three connected to it would have 333/s each.
After that, we could base the coefficient for the vector on the difference of this scalar value and since it takes obstacles and distance into account, it would work more or less realistically.
Regarding point (3) above, imagine that instead of having only sure-100%-pass and nope-0%-wall you also have intermediate options. Instead of just a corridor and a wall you can also have i.e. broken window with 30% air pass. For example, at place on the map with distance [0] you've got the initial hole that generates flux 1000/sec. However at distance [2] there is a small air vent or a broken window with 30% air flow modifier. It means that it will limit the amount from incoming (2x500=1000) to 0.3x(2x500)=300/sec that will now flow further to the next areas. That will allow you to depressurize compartments with different speeds so the first few tiles will lose all air quickly and the rest of the deck will take some more time (unless the 30%-modifier window at point [2] breaks completely, etc).

How do I calculate which chunks should be loaded first in a voxel game?

I am developing a voxel game (i.e. Minecraft, Cube World, InifiniMiner, etc.) in the Unity3D game engine using C# as my programming language.
One chunk is 16x16x16 blocks big. My code loads one chunk from file in ~12ms and generates its mesh in ~3ms. I can live with that, that is fast enough for the current state of the game.
My question is: How can I create a loading list the most efficient way? The player moves all the time, he is in motion. The world loads chunks in the direction the player moves. There may also be high buildings, so a few chunks on top of each other. When the building is "in sight" (a certain distance reached), it should be loaded completely. Am I better off having 16x256x16 sized chunks like in Minecraft?
This is a quite complicated topic and I need to be pushed into the right direction, because there are a million ways of dealing with this, but I am trying to find a compromise between not too complex to implement and very fast. If your approach is very complex, do not hesitate leaving an answer. I have little to no clue how to approach this problem.
What I tried in the past: Sort the chunk list based on distance to the player. So the nearest chunks are loaded first, and the most far away ones last. This led to slow world loading for some reason as the chunks below and above the player were loaded first, too, but it is more important to load the chunks that are on the same height as the player, as he needs something to walk on and not fall off the world. The player is not slow, he has a moderate to high movement speed.
I should note that I store the chunks in a C# Dictionary. The key is the ChunkPosition (x,y,z in chunks, so the first chunk is 0,0,0 and his right neighbor is 1,0,0 etc.) and the value is the Chunk class, which holds all the chunk data, its blocks and so on.
If you need more information, please ask in the comments.
Thanks in advance!
Essentially, you want to find the chunk closest to [the player and where they are looking]. What I mean by this is, you don't want to load a chunk behind your player if you haven't loaded the ones in front yet. So, do something like (pseudocode)
int priority = -(distanceFromPlayer + closenessToCenterOfScreen);
So, you calculate how high priority the chunks are, then load them one by one according to their priority. In my example, the higher the distance from the player, the lower the priority, and the closer the chunk is to the centre of the (viewed) screen, the higher the priority. Then, check if the priority is below the view distance, and if it is, don't bother loading it because it's too far away.

Procedurally Generated Structures over large quantitys of chunks in 3D Terrain Generator

I am creating large scale worlds using 16*16*16 voxel chunks which are stacked up to 32*32*32 in dimensions and I have hit a bit of a Bump in the road so to speak.
I want to create large structures that span 20+*20+*20+ chunks in volume which are created from procedurally generated structures as well as using templates for some of the content. Now I have an issue. The visual render range is up to 32*32*32 chunks and while I have up to maybe 40*40*40 chunks held in memory at a time when possible.
The structures can be anything like towns, dungeons and roads. I was thinking something like perlin worms for roads and just lay them over the terrain in the x,z and then analyze the path for bridges etc..
The structures and collection of structures need to be pre-generated before the player is within visual range or work more like perlin noise does for heightmaps (best solution). (to avoid the players seeing the generator at work). They also need to be consistent with the world seed every time.
I have thought about this a bit and have 2 possible solutions.
1) Generate the structures based on a point of origin for the structure generator.
This causes several issues though as even if I generate from the center of the structure, the structures can easily cross into the potential visual range of the player.
2) Pre-Generate "unreachable" chunks and then page them in and out in order to generate the structures using the above method.
This also seems rather unnecessary.
Both methods need to analyze the terrain in large quantities for a valid location to spawn the structures.
I was hoping somebody might have a more organic solution or even just a simpler solution that doesn't require me to "Look" so far ahead.
Thank you in advance.
EDIT:
I had an idea for dungeon generation in which I generate point clouds/nodes for rooms.
Steps:
1) When the generator finds a "node" it creates an x, y and z size to create a box basing it from the originator point of the room** (centre or corner of the room) and the room type.
**x,y,z relative to 0,0,0 worldspace calculated like so new Vector3((chunkX*16)+voxelX,(chunkY*16)+voxelY,(chunkZ*16)+voxelZ)
2) Once a room size is calculated, check for overlaps and if one is found do one of several things.
If the room overlap is high up lower it down till either the roof or the floor are flush. If the roof is flush build a stairs up to the room and remove the walls that intersect.
3) Look Down, North and East for a room maybe with a small cone and attempt to create a hallway between them.
This would probably work somewhat, especially if the center of the dungeon is the main hall/boss room.
This would be different for towns, cities, and surface dungeons. Still seems a little choppy though. Any ideas?
I faced a similar problem for a Minecraft mod I am writing. I want to have a number of overlapping "empires" which each create structures. But I don't want the structures to step on each other.
So, for this, I broke the world into arbitrary sized tiles. (Compare to your 32x32x32 regions.) I also came up with a "radius of influence". This is how far from the center point that it could create structures. Each tile had an instance of a provider class assigned to it with a unique seed.
Two methods on this class were provided for structure generation.
First, was a function that would return where it wanted to create structures. But only to the resolution of chunks. (Compare to your 16x16x16 block sets.) Each provider class instance had a priority, so in the case of two providers trying to rezz a structure in the same chunks, the higher priority one would win.
The second function would be passed a world instance, and one of the data items returned by the first function and would be asked to actually create it.
Everything pieces together like this:
We get a request to resolve a certain chunk of the world. We work out the provider for the tile the chunk is in, and then all the providers for all the tiles that are within the maximum radius of that tile. We now have every provider that could influence this chunk. We call the first function on each of them, if they haven't been called already, and register what chunks each of them has claimed into a global map.
At this point, we've consulted everything that could have an influence on this chunk. We then ask that registry if someone has claimed this chunk. If so, we call back into that provider (method #2) with the chunk and the world instance and get it to draw the bits for this part of its structure.
Does that give you enough of an idea for a general approach to your problem?

How to effeciently spread objects on a 2D surface in a "natural" way?

i would like to effeciently generate positions for objects on a given surface. As you probably guessed this is for a game. The surface is actually a 3D terrain, but the third dimension does not matter as it is determined by terrain height.
The problem is i would like to do this in the most effecient and easy way, but still get good results. What i mean by "natural" is something like mentoined in this article about Perlin noise. (trees forming forests, large to small groups spread out on the land) The approach is nice, but too complicated. I need to do this quite often and prefferably without any more textures involved, even at the cost of worse performance (so the results won't be as pretty, but still good enough to give a nice natural terrain with vegetation).
The amount of objects placed varies, but generally is around 50. A nice enhancement would be to somehow restrict placement of objects at areas with very high altitude (mountains) but i guess it could be done by placing a bit more objects and deleting those placed above a given altitude.
This might not be the answer you are looking for, but I believe that Perlin Noise is the solution to your problem.
Perlin Noise itself involves no textures; I do believe that you have a misunderstanding about what it is. It's basically, for your purposes, a 2D index of, for each point, a value between 0 and 1. You don't need to generate any textures. See this description of it for more information and an elegant explanation. The basics of Perlin Noise involves making a few random noise maps, starting with one with very few points, and each new one having twice as many points of randomness (and lower amplitude), and adding them together.
Especially, if your map is discretely tiled, you don't even have to generate the noise at a high resolution :)
How "often" are you planning to do this? If you're going to be doing it 10+ times every single frame, then Perlin Noise might not be your answer. However, if you're doing it once every few seconds (or less), then I don't think that you should have any worries about speed impact -- at least, for 2D Perlin Noise.
Establishing that, you could look at this question and my personal answer to it, which is trying to do something very similar to what you are trying to do. The basic steps involve this:
Generate perlin noise; higher turbulence = less clumping and more isolated features.
Set a "threshold" (ie, 0.5) -- anything above this threshold is considered "on" and anything above it is considered "off". Higher threshold = more frequent, lower threshold = less frequent.
Populate "on" tiles with whatever you are making.
Here are some samples of Perlin Noise to generate 50x50 tile based map. Note that the only difference between the nature of the two are the "threshold". Bigger clumps means lower threshold, smaller clumps means a higher one.
A forest, with blue trees and brown undergrowth
A marsh, with deep areas surrounded by shallower areas
Note you'll have to tweak the constants a bit, but you could do something like this
First, pick a random point. (say 24,50).
Next, identify points of interest for this object. If it's a rock, your points might be the two mountains at 15,13 or 50,42. If it was a forest, it would maybe do some metrics to find the "center" of a couple local forests.
Next, calculate the distance vectors between the the point and the points of interest, and scale them by some constant.
Now, add all those vectors to the point.
Next determine if the object is in a legal position. If it is, move to the next object. If it's not, repeat the process.
Adapt as necessary. :-)
One thing: If you want to reject things like trees on mountains you don't add extra tries, you keep trying to place an object until you find a suitable location or you've tried it a bunch of times and you need to bail out because it doesn't look placeable.

Categories

Resources