Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Peanut Butler
Jul 25, 2003



nice okay, thx for tips! too many helpful ppl to quote- going to read up on dataclasses, half of this project is getting more comfortable with python beyond knocking together quick system automation scripts, so it seems like a perfect opportunity

D34THROW posted:

I didn't even think of using lists or tuples; last time I was parsing a dice roll, I passed it as "XdY+N" as a string, splitting on "d" and then splitting again on "+" or "-", similar to:

I imagine, in such a situation where you're, say, reading something from a database where the "dice" field contains an "XdY" formatted item, plus "modifier" field of the format "+/-N", the string method (or even a dice_roll(num_sides: int, modifer: int = 0) method might be handy.

my diceparse function splits by [d+-] and then replaces "" or a missing list element with [1,6,0] respectively so that "d20" is [1,20,0], "3d" is [3,6,0], etc

it then splits by [0-9] and if the second element is a -, it multiplies the third element of the original by -1

later I want to expand on this and support notation like 2d20kh1 (keep highest 1, standard dnd advantage roll) but I'm moving on to sketching out other features before I come back to that

e: yes technically it re.splits and actually I don't have a clue if that's more or less expensive than multiple vanilla splits

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Peanut Butler posted:

e: yes technically it re.splits and actually I don't have a clue if that's more or less expensive than multiple vanilla splits
In general the allocations (and eventual garbage collection) are the most expensive part of that kind of thing, so whichever one has fewer intermediate strings is probably best. But also, this seems like a completely unnecessary thing to worry about optimization on, it's not the sort of thing you're going to be doing hundreds of times per frame.

KillHour
Oct 28, 2007


As someone who is forced to work with Javascript, I loathe string manipulation and avoid it as much as possible, regardless of performance considerations.

Basically I'm saying don't write this in JS.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug
I'm trying to develop a cover mechanic mimicking MGS3. I'm using Unity (2020.3), a Cinemachine Freelook camera and the new Input System. Directional Input is captured in a Vector2 when the movement event is broadcast.

I would like when in cover and player maintains directional movement into cover:

- Camera Direction is perpendicular to cover, player is idle
- Camera Direction changes by -Y (rotating to player right), player starts moving left
- Camera Direction changes by +Y (rotating to player left), player starts moving right
- Player movement input changing to the direction of the wall after camera movement should return player to idle
- Camera Direction returning to perpendicular view angle should return player to idle

Movement should then also be influenced by directional input relative to the players facing. Relative directional input becoming parallel with cover should cause the player to exist cover.

Efforts towards a solution

My current implementation only works when the player is facing in either direction on the X axis. When in cover with a facing on the Y axis, movement (induced from either Camera or input) the player does move, but in the wrong direction.

Code:

code:
Vector2 movementInput;

private void OnMove(InputValue value)
{
	movementInput = value.Get<Vector2>();
}

private void Update()
{
	coverBehavior.HandleUpdate(movementInput);

	var input = new Vector3(movementInput.x, 0f, movementInput.y);
	if (coverBehavior.IsInCover)
	{	
		var camAngles = Camera.main.transform.rotation.eulerAngles;
		camAngles.Set(0f, camAngles.y, 0f);
		var camRotation = Quaternion.Euler(camAngles);
		input = camRotation * transform.rotation * input;
	}

	SetFloat(PlayerAnimations.MoveX, input.x);
	SetFloat(PlayerAnimations.MoveY, input.z);

	playerAnimator.SetBool(PlayerAnimations.InCover, coverBehavior.IsInCover);
}

Vector3 GetCameraForward()
{
	Vector3 forward = Camera.main.transform.forward;
	forward.y = 0f;
	return forward.normalized;
}
Dot Product

The Dot Product of Camera Direction and Player Right give potential movement in camera direction. What I'm falling short on determining is how to properly transform directional input, or if that's even the right approach. I don't think this is the right approach because movement isn't really caused by the Camera Direction in MGS3, it's caused by the effects Camera Direction has on directional input.

code:
var camFwd = GetCameraForward();
var playerRight = transform.right;
playerRight.y = 0;
var dot = Vector3.Dot(camFwd, playerRight);
var positionalInput = transform.rotation * input;
input.x = -dot;
This produces movement in the correct direction based on camera position, but I struggle to properly modify it by directional input. This is what leads me to think that my current approach may be closer if currently flawed.

Which of these approaches seems most reasonable/cheaper to perform, or are my problems rooted in the fact both approaches are wrong?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Assuming you're not deliberately making a Resident Evil callback by using unplayable tank controls, you should determine your absolute input by multiplying the controller input by the camera rotation, and not caring at all about the player rotation.

Gin_Rummy
Aug 4, 2007
Is there a simple way to replace a game object's geometry in Unity? For example, if I started something as a cube, can I easily swap it out with an asset from the store?

EDIT: So that it keeps all the same scripts, associations, etc

Gin_Rummy fucked around with this message at 01:14 on Oct 6, 2021

Raenir Salazar
Nov 5, 2010

College Slice

Gin_Rummy posted:

Is there a simple way to replace a game object's geometry in Unity? For example, if I started something as a cube, can I easily swap it out with an asset from the store?

Yup. Load up blender, make a new model, export as an FBX, drag and drop into your project and replace the mesh in the mesh renderer component and you're done; you might need to play around with your settings so up is not down and right is not left and it isn't either tiny as a flea or the size of the titanic but you get the idea.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Raenir Salazar posted:

Yup. Load up blender, make a new model, export as an FBX, drag and drop into your project and replace the mesh in the mesh renderer component and you're done; you might need to play around with your settings so up is not down and right is not left and it isn't either tiny as a flea or the size of the titanic but you get the idea.

It's the mesh filter component, but yeah, you can swap meshes in/out no problem.

Gin_Rummy
Aug 4, 2007
If only Blender wasn't the worst 3D modeling tool ever created :(

I do have an asset I created in ProBuilder (as well as a janky one imported from Blender), but neither show up in my options on the mesh filter.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Make sure you're trying to use the mesh. Blender objects generally get imported as a prefab that contains a mesh, so you have to open them up to access the mesh asset.

Lork
Oct 15, 2007
Sticks to clorf

Gin_Rummy posted:

If only Blender wasn't the worst 3D modeling tool ever created :(

I do have an asset I created in ProBuilder (as well as a janky one imported from Blender), but neither show up in my options on the mesh filter.
What filetype did you export them as? Unity uses .fbx files for 3d models.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug

Jabor posted:

Assuming you're not deliberately making a Resident Evil callback by using unplayable tank controls, you should determine your absolute input by multiplying the controller input by the camera rotation, and not caring at all about the player rotation.

It's not RE style movement, it's Metal Gear Solid style movement while in cover. The player is locked into movement along their local X axis. I figured it out eventually and the solution is to use the Dot Product of the input (multiplied by camera forward/right) and players transform.right. This gives movement along local X based on directional input and camera angle, a la Metal Gear Solid 3. There might be a shorter way to express the camera stuff, but this is the idea written minimally.

code:
var input = new Vector3();
input += directionalInput.x * GetCameraRight();
input += directionalInput.y * GetCameraForward();

var moveDot = Vector3.Dot(input, transform.right);
transform.Translate(moveDot * Time.deltaTime, 0, 0);

Dr. Poz fucked around with this message at 16:39 on Oct 6, 2021

CH Science
Sep 11, 2019

I have a probably dumb question. Kinda new to 3D transforms. Using Godot but that shouldn’t matter much as it doesn’t seem to offer a dedicated function for what I need and honestly I just wanna know how the math works.

Say I have two objects:

I can get the Euler (or Quat if that changes things) of each to get each ones rotation in game space or relative to the parent or whatever

What I want is to measure “is the rotation of firstObject different from the rotation of secondObject by arbitrary amount”

So if the-thing-that-determines-where-the-feet-should-go’s rotation is different enough from the thing-that-determines-where-the-character-is-aiming’s rotation, do a thing (in this case a little step animation to reset the feet so they aren’t backwards when spinning around)

Is there a way to calculate this? All my searching comes up with “how to determine the angle from one Vector3 to another” which is not really helpful when what I really want to do is compare the rotations of the two regardless of where they are in the game space.

Thanks in advance as always

chglcu
May 17, 2007

I'm so bored with the USA.

CH Science posted:

I have a probably dumb question. Kinda new to 3D transforms. Using Godot but that shouldn’t matter much as it doesn’t seem to offer a dedicated function for what I need and honestly I just wanna know how the math works.

Say I have two objects:

I can get the Euler (or Quat if that changes things) of each to get each ones rotation in game space or relative to the parent or whatever

What I want is to measure “is the rotation of firstObject different from the rotation of secondObject by arbitrary amount”

So if the-thing-that-determines-where-the-feet-should-go’s rotation is different enough from the thing-that-determines-where-the-character-is-aiming’s rotation, do a thing (in this case a little step animation to reset the feet so they aren’t backwards when spinning around)

Is there a way to calculate this? All my searching comes up with “how to determine the angle from one Vector3 to another” which is not really helpful when what I really want to do is compare the rotations of the two regardless of where they are in the game space.

Thanks in advance as always

acos(dot(normalize(vec1),normalize(vec2))) sounds right to me for that, but math isn’t my strong suit.

e: to elaborate about, the dot product of two vectors is equal to the product of their lengths and the cosine of the angle between them. if the vectors are normalized, lengths are 1, so the dot product of two normalized vectors equals the cosine of the angle between them.

chglcu fucked around with this message at 05:02 on Oct 7, 2021

CH Science
Sep 11, 2019

So inverse cosine of the dot product of the two? I will try that and report back. Thanks!

chglcu
May 17, 2007

I'm so bored with the USA.

CH Science posted:

So inverse cosine of the dot product of the two? I will try that and report back. Thanks!

yep, if the vectors are length 1, hence the normalize in what I posted. Can be skipped if they’re already unit length.

chglcu
May 17, 2007

I'm so bored with the USA.
As a side note, this is useful to know since it, for example, allows you to find what side of a plane a point is on or whether two vectors are facing toward or away from each other, just by checking the sign of the dot product.

CH Science
Sep 11, 2019

chglcu posted:

As a side note, this is useful to know since it, for example, allows you to find what side of a plane a point is on or whether two vectors are facing toward or away from each other, just by checking the sign of the dot product.

That’s… super useful, awesome.

chglcu
May 17, 2007

I'm so bored with the USA.

CH Science posted:

That’s… super useful, awesome.

Yeah, what the dot product actually represents is very useful to know, and something that game dev tutorials always gloss over in my experience. As someone who dropped out of school before stuff like that was covered it was really eye opening when someone actually bothered to mention it.

CH Science
Sep 11, 2019

Yep my experience exactly. Thanks

Peanut Butler
Jul 25, 2003



roomforthetuna posted:

In general the allocations (and eventual garbage collection) are the most expensive part of that kind of thing, so whichever one has fewer intermediate strings is probably best. But also, this seems like a completely unnecessary thing to worry about optimization on, it's not the sort of thing you're going to be doing hundreds of times per frame.

yeah lol I'm starting to realize that most of my coding habits were formed on <12MHz machines

python can get v slow on my netbook if it's doing graphical or ncurses displays but I think that's more a case of using a tool made for a different task

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Peanut Butler posted:

yeah lol I'm starting to realize that most of my coding habits were formed on <12MHz machines
I get it, I'm the same way. I'll do *0.5 rather than /2.0 just in case the compiler for the language I'm using doesn't optimize const-divides to equivalent const-multiplies because hey that saves 4 cycles or something. But I try to keep myself to only doing it in places where it's basically equivalent, rather than digging deep into decisions about using different libraries and APIs for the optimization of a thing that isn't actually performance-critical.

12 rats tied together
Sep 7, 2006

giogadi posted:

I recommend gamemath.com

It’s free, well written, and keeps everything focused and motivated for video games.

this is a very good link, thank you for posting it

D34THROW
Jan 29, 2012

RETAIL RETAIL LISTEN TO ME BITCH ABOUT RETAIL
:rant:
Alright, I've worked out some of the basics of this thing, enough to start a SQLite database and some rudimentary rules and gameplay flow. This may or may not become something more than a digital TCG, I'm picturing more of a Soda-Dungeo meets MtG sort of thing? Dropping the general abstract/flow here for comments and questions.

quote:

Project Caelina is the working name of a digital trading card game being developed by BlackRed Studios. It is based on a system wherein hero cards use equipment to attack the opponent's heroes and then commander, reducing their influence to zero in order to win the match.

Warrior-type heroes are equipped with some combination of weapons and shields - either a "two-handed" weapon, a "one-handed" weapon and a shield, or two "one-handed" weapons. Wizard-type heroes are equipped with a staff and one to three spells that require a certain amount of mana (of either fire, water, earth, air, light, or dark varieties)* to cast.

Each hero's core statistics include power (for warriors) or mana (for wizards), alignment, a description, and possibly a special effect. They cost gold to summon, which is earned through income from commanders and stored in the player's bank. Each hero also has incidental statistics, which include a hero's number, height, weight, and age. These are exclusively for flavor text - they do not affect gameplay in any way.

Game/Turn Flow

Play begins with each player shuffling their commander deck, then drawing four cards and selecting one to be their commander for the duration of the game. Once the commander is drawn and in play, the Recruiter, Armory, and Tower decks are shuffled and placed facedown.

Play then proceeds as follows:

1) During the initial phase - the recruiting phase, the player can play a hero card or defer if they already have six heroes in play, or do not wish to play a hero at that time.

2) During the equipping phase, the player fills any vacant equipment slots on their cards, both newly played and recently disarmed characters.

3) During the magical phase, wizard cards utilize one equipped spell each.

4) During the physical phase, warrior cards utilize their equipped weapons and any relevant effects.

5) During the draw phase, the player draws back up to three cards each from their Recruiter, Armory, and Tower deck, for a total of nine base cards plus any cards drawn as the result of spell effects, up to a maximum of twelve cards.

Play continues in this manner until one commander's influence is reduced to zero, or until a player's Recruiter deck is exhausted and they can no longer play new heroes.

Possible Revisions

* Considering a change from English to Latin for the mana types (ignis, aqua, terra, caelum, lux, tenebris)

I'm also considering something like ignum/aquum/terrum/caelum/luxum/tenebrum for some sort of additional flavor. Thoughts?

One more question - would it make more sense to have one SQLite database for each type of card or store the type as a field?

MikeJF
Dec 20, 2003




roomforthetuna posted:

I get it, I'm the same way. I'll do *0.5 rather than /2.0 just in case the compiler for the language I'm using doesn't optimize const-divides to equivalent const-multiplies because hey that saves 4 cycles or something. But I try to keep myself to only doing it in places where it's basically equivalent, rather than digging deep into decisions about using different libraries and APIs for the optimization of a thing that isn't actually performance-critical.

Would there be any compilers these days that don't optimise that kind of thing standard?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

MikeJF posted:

Would there be any compilers these days that don't optimise that kind of thing standard?
I wouldn't be surprised if Dart's compiler didn't. It's inadequate at a lot of things.

Killed By Death
Jun 29, 2013


Are there any good resources (video/blog/book etc) that go into how to implement rebindable controls in a sane manner? I have a very basic outline in my head i.e. OS layer "VKCode == `W`" -> translation layer "Keyboard.W" -> some assignment to abstract buttons somehow(?) "Character.MoveFoward.IsDown()", but I'm not thrilled about it, and I know this is a space that's already been explored.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Killed By Death posted:

Are there any good resources (video/blog/book etc) that go into how to implement rebindable controls in a sane manner? I have a very basic outline in my head i.e. OS layer "VKCode == `W`" -> translation layer "Keyboard.W" -> some assignment to abstract buttons somehow(?) "Character.MoveFoward.IsDown()", but I'm not thrilled about it, and I know this is a space that's already been explored.

Define a list of actions the user can make. Have an event for each action. Trigger the event when a user configured key is pressed.

more falafel please
Feb 26, 2005

forums poster

leper khan posted:

Define a list of actions the user can make. Have an event for each action. Trigger the event when a user configured key is pressed.

This. One layer further would be defining a list of input events (key down, key up, axis change) and a list of actions, and have a double-blind mapping between them. That helps when you want to support an input system that isn't what you originally planned (keyboard/mouse to controller, touch controls, etc).

Another thing to think about is different mappings: swapping the set of mappings based on what has input focus, gameplay vs. UI being the main use case.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
If you possibly can, find an asset that does input handling for you. I use Rewired in Unity and it was absolutely the right choice. Unity apparently has a new input layer now but I've heard it has some annoying edge cases. The nice thing about doing this, instead of rolling your own, is that the assets will have broader support for different kinds of input. For example, Rewired supports hundreds of different gamepads transparently, including niche console setups. Rewired also has support for input remapping out of the box -- there's a pre-made UI prefab you can customize that will show the player all of the input actions you've set up, with the ability to change what they're bound to. It's a decently complicated scene, and when I started working on customizing it, I realized there's a poo poo-ton of edge cases here if you want to do it right, so I'm very glad that someone else has already done the work for me.

As for feeding inputs to your code, I wouldn't actually personally use the event system. I find it easier to have my code query the input layer for inputs during each update tick. In particular, I find that this makes it easier for me to shunt input to only the specific bits of code that are currently listening. I wrote a wrapper around Rewired that I call InputDirector, and any code that wants to be able to access input data first has to push itself onto a stack as a listener. Then when it queries for input, it has to pass itself along (e.g. InputDirector.GetButtonDown(this, InputDirector.FIRE)). InputDirector then looks at its stack to decide if that listener is currently allowed to receive input, and if it isn't, then it gets back "no input".

This lets me do things like just leave the player controller running when the game is paused. The pause menu pushes itself as a blocking listener when it comes up, and the player simply stops getting input. Then when the user accesses the options menu from the pause menu, the options UI pushes itself, and the pause menu stops getting input. When the user backs out of these UIs, they pop themselves, and the layers underneath start getting input again. It's very easy to think about. Every once in awhile you'll get a situation where some code dismissed its UI but didn't stop listening for input, or something like that, but that's easy to fix.

CodfishCartographer
Feb 23, 2010

Gadus Maprocephalus

Pillbug
Quick DoTween question, since I think some people here use it - what's the best way to make an ordered sequence of tweens? AKA, do one tween, then when it's finished, do a second. I know there's DOTween.Sequence() but whenever I use that it seems to play everything on it at the same time, rather than waiting. This is how I have them set up:

code:
Sequence example = DOTween.Sequence();

        example.Append
        (
            transform
            .DOLocalRotate(Vector3.one, 2f)
            .SetEase(Ease.OutQuint)
        ).Append
        (
            transform
            .DOLocalRotate(Vector3.zero, 1f)
            .SetEase(Ease.OutQuint)
        )
        .Play();

TIP
Mar 21, 2006

Your move, creep.



CodfishCartographer posted:

Quick DoTween question, since I think some people here use it - what's the best way to make an ordered sequence of tweens? AKA, do one tween, then when it's finished, do a second. I know there's DOTween.Sequence() but whenever I use that it seems to play everything on it at the same time, rather than waiting. This is how I have them set up:

code:
Sequence example = DOTween.Sequence();

        example.Append
        (
            transform
            .DOLocalRotate(Vector3.one, 2f)
            .SetEase(Ease.OutQuint)
        ).Append
        (
            transform
            .DOLocalRotate(Vector3.zero, 1f)
            .SetEase(Ease.OutQuint)
        )
        .Play();

You can just stick a callback function into an OnComplete like this:
transform.DOMoveX(4,1).OnComplete(MyCallback);

Raenir Salazar
Nov 5, 2010

College Slice
I have made some additional progress, after my initial proof of concept I have moved on to actually getting "what I want" from the thing.

Here's a 1024 by 512 texture of """simplex""" noise. Apparently it isn't enough to simply use 3D noise if I want the noise to wrap around but ultimately I think while nice to have probably isn't necessary as we'll see.

Noise:


Falloff+Water Level mask applied and then a colour ramp to get the silhouettes:


Tag yourselves, I'm the mini Westeros down by the bottom of the "New World" continent.

I actually like these results so much I went and married them I saved the settings and plugged them in as my defaults.

I haven't implemented yet a means of blending them as currently that's a tad pointless, as I'll explain below. But I threw the two images into Paint.net and slapped on some contrast:



The "mountains" might not be the best, I want to layer ontop some ridged noise or perturbed noise to try to get more natural looking ridge lines but in most applications that use ridged noise its in a 3D application and not one where the noise ends up being normalized... Simply multiplying the two noise height maps together doesn't give particularly visible results because simply multiplying two floats kinda results in an averaged result.

An interesting procedural world gen challenge is since I want to first make this generate playable mods for the Paradox games, where would "Europe" be? How would we determine the best location algorithmically?

Top left of the larger continent? Top right? Bottom left? Bottom-Bottom-Right? Might be too challenging a question for me to implement a solution. But if I am able to at least figure out how to divide up the landmass into zones its an interesting question to ponder.

(With the height map applied, a good candidate for "Europe" might be the middle-left Gondor looking area which looks to be surrounded by protective mountains; "China" could be the top right which seems mainly hilly and less mountainy than the other areas.

My next step which is to categorize the map's features such as the number and size of land and water masses I can just do on the original height map using my water level and fall off settings as part of the flood fill (scanline) calculation.

Basic idea is islands or water inlets that are too small will be eliminated; I'll have a list of all land pixels divided into different lists and from there I will randomly generate points for my voronoi/delaney map.

For Europa IV, there's 3200 or so land provinces, and then maybe 1,000 or so sea tiles, so assuming a generous upper bound of 4,500 tiles, and for a 8k by 4k texture map thats over 33,000,000 pixels; so considering 71% of the globe is covered by water, thats 10 million or so pixels, I think makes the average province 2,500 pixels in area with the average sea tile being 24,000 pixels.

Islands in EU4 and other games can be quite small, so I think the cut off on which islands to eliminate might have to be quite small, like sub 100 pixels while also being sufficiently far from land such that it can't just be merged together.

chglcu
May 17, 2007

I'm so bored with the USA.
If you want to wrap just on one axis, I think you should be able to map the x,y position to their 3d position on a cylinder and use those as your noise inputs.

The equations for this should be similar to texture mapping a cylinder.

chglcu fucked around with this message at 04:58 on Oct 15, 2021

Raenir Salazar
Nov 5, 2010

College Slice

chglcu posted:

If you want to wrap just on one axis, I think you should be able to map the x,y position to their 3d position on a cylinder and use those as your noise inputs.

The equations for this should be similar to texture mapping a cylinder.

Yeah I had found some psuedo code already for it but I'm applying a fall off mask to my map along both axis anyways so I didn't feel the need to go further:

code I found:
code:
// three dimensional cylindrical map
drawNoise(function(i,x,y){
    var fNX = x/iSize
        ,fRdx = fNX*2*Math.PI
        ,a = fRdsSin*Math.sin(fRdx)
        ,b = fRdsSin*Math.cos(fRdx)
        ,v = Simplex.noise(
             123+a*fNoiseScale
            ,132+b*fNoiseScale
            ,312+y*fNoiseScale // similar to the one dimensional loop but we add a third dimension defined by the image y-offset
        )
    ;
    return v*255<<0;
}).img().div(2);

Raenir Salazar
Nov 5, 2010

College Slice
Anyone happen to know why this algorithm from Wikipedia for a scanline non-recursive floodfill doesn't seem to work?

code:
fn fill(x, y):
  if not Inside(x, y) then return
  let s = new empty queue or stack
  Add (x, x, y, 1) to s
  Add (x, x, y - 1, -1) to s
  while s is not empty:
    Remove an (x1, x2, y, dy) from s
    let x = x1
    if Inside(x, y):
      while Inside(x - 1, y):
        Set(x - 1, y)
        x = x - 1
    if x < x1:
      Add (x, x1-1, y-dy, -dy) to s
    while x1 < x2:
      while Inside(x1, y):
        Set(x1, y)
        x1 = x1 + 1
      Add (x, x1 - 1, y+dy, dy) to s
      if x1 - 1 > x2:
        Add (x2 + 1, x1 - 1, y-dy, -dy)
      while x1 < x2 and not Inside(x1, y):
        x1 = x1 + 1
      x = x1
If I use the points (0,0) in a 512 by 256 pixel texture, it just exits immediately and doesn't start exploring towards the right.

x is 0 and x - 1 is -1 and so doesn't set anything on that first if/while block. 0 is not "less than" 0 so it doesn't do Add (x, x1-1, y-dy, -dy) to s, and x1 is of course not less than x2 so of course it doesn't do anything in the while x1 < x2 where the going from 0 to .... I would expect to happen along the x axis.

I am assuming that when it says:

Add (x, x, y, 1) to s
Add (x, x, y - 1, -1) to s

That given (x,y) which is (0,0) then it wants to enqueue:
(0,0,0,1) and
(0,0,-1,-1).

With that "Remove an (x1, x2, y, dy) from s" means that a tuple of four elements the elements are named: x1 (first element), x2 (second element), y (3rd element), and dy (4th).

So tracing through:

let x = x1 means x is 0.

(0,0) is Inside but x-1 is not.

if x < x1: well 0 < 0 is false, so skip.

while x1 < x2: 0 < 0 is also false, so skip.

Nothing changes for the second element in the queue s and so nothing happens for another iteration. Then there's no elements left.

Raenir Salazar fucked around with this message at 06:22 on Oct 18, 2021

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
Well the wikipedia page mentions that their version "corrects some bugs in the original." It's quite possible the wikipedia version is buggy, and your analysis appears right to me on first read.

Now, I was able to track down the supposedly buggy "original," maybe you'll find it helpful. ov = "old value", nv = "new value." If you do figure out what's wrong with that wikipedia code, be sure to mention it. I'd like to correct the article if possible.

code:
begin  procedure  fill
	ov  <-  pixelread(x,  y); #read  pixel  value  at  seed  point
	if  ov  =  nv  or  x  <  win.xmin  or  x  >  win.xmax  or  y  <  win.ymin  or  y  >  win.ymax  then
		return;
	push(y,  x,  x,  1); #needed  in  some  cases
	push(y  +  1,  x,  x,  –1); #seed  segment(popped  1st)
	
	while  sp  >  0  do
		#pop  segment  off  stack  and  fill  a  neighboring  scan  line
		pop(y,  x1,  x2,  dy);

		#segment  of  scan  line  y  –  dy  for  x1  <=  x  <=  x2  was  previously  filled,
		#now  explore  adjacent  pixels  in  scan  line  y
		x  <-  x1;
		while  x  >=  win.xmin  and  pixelread(x,  y)  =  ov  do
			pixelwrite(x,  y,  nv);
			x <-  x  –  1;
		endloop;

		if  x >= x1  then  goto  skip;
		start  <-  x  +  1;
		if  start  <  x1  then  push(y,  start,  x1  –  1,  –  dy); #leak  on  left?
		x <- x1  +  1;

		loop  do
			while  x <= win.xmax  and  pixelread(x,  y)  =  ov  do
				pixelwrite(x,  y,  nv);
				x  <-  x  +  1;
			endloop;
			
			push(y,  start,  x  –  1,  dy);

			if  x   >   x2  +  1  then  push(y,  x2  +  1,  x  –  1,  –  dy); #leak  on  right?
skip: 			x  <-  x  +  1;
			while  x  <=  x2  and  pixelread(x,  y)  != ov  do
				x  <-  x  +  1;
			endloop;
			start  <-  x;
		while  x  <=  x2;
	endloop;
endproc  fill;
This version also appears buggy (it only ever pushes the same y value as it popped, for example)

Edit: Oh, it's assumed that the pop function adds dy to y. It's also assumed that the push function doesn't push if y+dy is out of bounds

HappyHippo fucked around with this message at 23:05 on Oct 18, 2021

Raenir Salazar
Nov 5, 2010

College Slice
Yeah someone just pointed out to me that version as well, mega-oof if its also buggy though. :(

e: Just saw your edit, yay! Much rejoicing!

e2:


I'm glad you took the time to write it out and format it better because in the link to the pdf the alignment of the code doesn't line up very well. That loop do while loop in particular isn't clear.

e3: I just noticed but when it says "y + dy <= win.ymax" is the psuedocode 1 indexed instead of 0 indexed?

Raenir Salazar fucked around with this message at 03:32 on Oct 19, 2021

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
(Crossposted from the Making Games Megathread)

I'm having some trouble with jitter in a cinematic I'm working on:

https://i.imgur.com/SkIiu7g.mp4

First there's the shadow jitter, which you can see at the beginning as the camera pulls out. It is not affected by actual lighting settings -- I can bracket the shadow near and far planes precisely on the airplane, change the biases, etc. and it'll still flicker. It does go away entirely if I turn off the main camera's CinemachineBrain, but no setting I've changed on the virtual camera itself has affected the jitter. The virtual camera is using a Transposer body and Composer aim, and it's following an empty that has a CinemachineDollyCart on it, which is tracking a CinemachineSmoothPath in LateUpdate. The airplane is similar, using a dolly cart to follow a path in Update.

The second is the jitter in the apparent movement of the airplanes. This is especially noticeable when they start their dives. I have no idea what's causing this. The camera's not moving much during this period, and the jitter's still visible even if I lock it in place. It feels like I'm dropping frames or something, but the editor reports that it's consistently staying well above 60FPS.

Any ideas?

Adbot
ADBOT LOVES YOU

Raenir Salazar
Nov 5, 2010

College Slice

TooMuchAbstraction posted:

(Crossposted from the Making Games Megathread)

I'm having some trouble with jitter in a cinematic I'm working on:

https://i.imgur.com/SkIiu7g.mp4

First there's the shadow jitter, which you can see at the beginning as the camera pulls out. It is not affected by actual lighting settings -- I can bracket the shadow near and far planes precisely on the airplane, change the biases, etc. and it'll still flicker. It does go away entirely if I turn off the main camera's CinemachineBrain, but no setting I've changed on the virtual camera itself has affected the jitter. The virtual camera is using a Transposer body and Composer aim, and it's following an empty that has a CinemachineDollyCart on it, which is tracking a CinemachineSmoothPath in LateUpdate. The airplane is similar, using a dolly cart to follow a path in Update.

The second is the jitter in the apparent movement of the airplanes. This is especially noticeable when they start their dives. I have no idea what's causing this. The camera's not moving much during this period, and the jitter's still visible even if I lock it in place. It feels like I'm dropping frames or something, but the editor reports that it's consistently staying well above 60FPS.

Any ideas?

I don't know too much about that kind of graphics pipeline to be of help but I love the cinematic feel you're going for! I love that combination of like Star Wars, Star Fox and Ace Combat you're doing.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply