#JavaFX Fluid Simulation
1 messages ยท Page 2 of 1
ok nvm ๐ญ
it does prevent the moving but it doesn't accept it as a keybind
so i guess i gotta do something about that
is settingsPane the tabpane?
yep
ahh
wait nvm
it won't work
wait
i am maybe a genius
hold on a sec
so i have this method
@FXML
public void onKeyPressed(KeyEvent keyEvent) {
if (setKeyBindFlag) {
keyBindMap.put(recentlyPressedAction, keyEvent.getCode());
buttonMap.get(recentlyPressedAction)
.setText(keyEvent.getCode()
.getName()
.toUpperCase());
changeButtonColor(recentlyPressedAction, primaryButtonColor);
setKeyBindFlag = false;
}
}```
Detected code, here are some useful tools:
i could just do this no?
settingsPane.addEventFilter(KeyEvent.ANY, keyEvent -> {
if (keyEvent.getCode()
.isArrowKey()) {
onKeyPressed(keyEvent);
keyEvent.consume();
}
});```
probably works
but I am not sure if thats a good solution though
WOOOOO
lol
how come ๐ญ
javafx internally should handle events, but now you are firing your event outside of that
but whatever
it's not tooo much of a big deal yeah
OK
i can now move onto my graphics settings
I am going to find out if there is a better way
and you can continue working on other stuff
i should be done with this main menu prototype within the next 2 hours
sure!
btw
quick question
do you do a cs degree lmao
ohhh same
but im doing maths ๐ญ
hence why i suck with gui stuff
i do love the logic side of cs though
try this:
tabs.setEventDispatcher((event, chain) -> {
if (event instanceof KeyEvent keyEvent) {
if (keyEvent.getCode().isArrowKey()) {
event.consume();
}
}
return chain.dispatchEvent(event);
});
hm ok :D
how should i make it so i can change these settings ๐ญ
i changed the fluid cace one
make them buttons
then if you click on them you handle it
are there specific options for cell size for example?
so the user can switch between 10x10, 100x100, ... and not any value of N?
yeahh
otherwise you would want text inputs
then button will work
if the user clicks on it it is going to jump to the next value of the possible ones
you could
but also a normal list will work
so like lets say FPS i would have 20 -> 30 -> 45 -> 60 -> 75
yeah and then i can just use mod
yeah anything would work here tbh
you might want to create a custom class for graphics settings
and have an instance of that in the controller
GraphicsHandler?
yeah why not
i made a circular linked list
for the marks
package com.fluidity.program.utilities;
import javafx.scene.Node;
public class CircularLinkedList<T> {
private LinkedListNode<T> head;
private LinkedListNode<T> tail;
public CircularLinkedList() {
head = null;
tail = null;
}
public CircularLinkedList(T[] initalList) {
for (T item : initalList) {
addNode(item);
}
}
public void addNode(T value) {
LinkedListNode<T> newNode = new LinkedListNode<>(value);
if (head == null) {
head = newNode;
} else {
tail.nextNode = newNode;
}
tail = newNode;
tail.nextNode = head;
}
public void deleteNode(T valueToDelete) {
LinkedListNode<T> currentNode = head;
if (head == null) {
return;
}
do {
LinkedListNode<T> nextNode = currentNode.nextNode;
if (nextNode.payload == valueToDelete) {
if (tail == head) {
head = null;
tail = null;
} else {
currentNode.nextNode = nextNode.nextNode;
if (head == nextNode) {
head = head.nextNode;
}
if (tail == nextNode) {
tail = currentNode;
}
}
break;
}
currentNode = nextNode;
} while (currentNode != head);
}
public boolean containsNode(T searchValue) {
LinkedListNode<T> currentNode = head;
if (head != null) {
do {
if (currentNode.payload == searchValue) {
return true;
}
currentNode = currentNode.nextNode;
} while (currentNode != head);
}
return false;
}
}
package com.fluidity.program.utilities;
public class LinkedListNode<T> {
public T payload;
public LinkedListNode<T> nextNode;
public LinkedListNode(final T payload, final LinkedListNode<T> nextNode) {
this.payload = payload;
this.nextNode = nextNode;
}
public LinkedListNode(final T payload) {
this.payload = payload;
this.nextNode = null;
}
public LinkedListNode() {
this.payload = null;
this.nextNode = null;
}
}
would have just used a normal list, but whatever
fair enough ๐ญ
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
I AM HOME
TIME TO CONTINUE THE PROJECT
ok
I must now start with the second prototype
I am not sure if i should conduct the testing first
surely i can just make the second prototype and test the first one separately?
prototype?
yeahh
so in my school we have to conduct the development in prototypes
like sections of devvelopment
i have broken mine down into the following:
Prototype 1 - Creating the main menu
Prototype 2 - Implementing the fluid functionality
Prototype 3 - Implementing the simulation functionality(Simulation Loop and rendering)
Prototype 4 - Barriers and Objects to place in fluid
Prototype 5 - Backtracking and saving the recordings of the fluid```
so I would first completely finish prototype 1 before starting with the second
hmm ok
the fluid should be first, a main menu is completelly optional
yeahh of course idk why i did that though
but
prototype 1 is done anyways
btw you can already put your project on github so I can give some feedback on your code
its easier if this is done step by step like the prototype stuff
@grand garnet
yeah sure
i'm just doing finishing touches on prototype 1
import java.awt.event.MouseEvent;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import static java.lang.Math.hypot;
public class MouseAdapter extends java.awt.event.MouseAdapter {
private int[] previousCoords;
private boolean mouseHeld = false;
private List<FluidInput> sourceQueue;
private Instant startAdd;
public MouseAdapter() {
sourceQueue = new ArrayList<>(); //TALK ABOUT LINKED LIST
startAdd = Instant.now();
}
public void mousePressed(MouseEvent e) {
previousCoords = new int[] { e.getX(), e.getY() };
mouseHeld = true;
startAdd = Instant.now();
}
@Override
public void mouseReleased(MouseEvent e) {
mouseHeld = false;
}
public synchronized void mouseDragged(MouseEvent e) {
double velocityX = 0;
double velocityY = 0;
double dragScalar = 5.0;
if (previousCoords != null) {
velocityX = dragScalar * ((double) e.getX() - previousCoords[0]);
velocityY = dragScalar * ((double) e.getY() - previousCoords[1]);
}
startAdd = Instant.now();
previousCoords = new int[] { e.getX(), e.getY() };
sourceQueue.add(new FluidInput(previousCoords[0], previousCoords[1] - (30), velocityX, velocityY,
6.0 * hypot(velocityX, velocityY)));
}
synchronized void consumeSources(Consumer<FluidInput> sourceConsumer) {
if (mouseHeld) {
long timeHeld = Duration.between(startAdd, Instant.now())
.toMillis();
startAdd = Instant.now();
sourceQueue.add(new FluidInput(previousCoords[0], previousCoords[1], 0, 0, timeHeld * 20.0));
}
for (FluidInput source : sourceQueue) {
sourceConsumer.accept(source);
}
sourceQueue.clear();
}
}
Detected code, here are some useful tools:
need help converting this into javafx stuff ๐ญ
you can copy most of it
just use the listeners/event handlers that fx use
you using javafx.scene.canvas.Canvas right?
you can just change the onMousePressed and onMouseReleased on that element
also this:
public class MouseAdapter extends java.awt.event.MouseAdapter
is very bad practice
why?
ahh ok
same reasons we've been recommending against it this whole time
.
it also looks weird when looking at the hierarchy, its the same as doing:
public class Dog extends different.location.Dog {
}
what makes it different?
Yeah looks nice
Yeah looks decent
The control elements on the right menu could get some redesign using css
hmm true
my justification for a grayscale simulation is for it to be accesssible for colorblind ๐ญ
today i couldnt' get much work done ๐ญ
had to go to my uncles wedding anniversary
imma go sleep now
imma just do my write up
gn
In Java, the forward slash ("/") at the beginning of a path represents an absolute path.
When you provide an absolute path, it means that you are specifying the complete and exact location of the file or resource you want to access. The absolute path starts from the root directory of your file system.
On the other hand, when you don't include a forward slash at the beginning of a path, it is considered a relative path. A relative path is interpreted relative to the current working directory or the location where your program is being executed.
By using an absolute path with a forward slash at the beginning ("/MainMenu.fxml"), you ensure that Java looks for the file in a specific and fixed location in your file system. This can be useful when you want to access resources that are stored in specific directories regardless of where your program is being executed from.
If you omit the forward slash ("MainMenu.fxml"), Java will interpret it as a relative path and look for the file in relation to the current working directory. This can lead to issues if your program is being executed from different locations or if there are multiple files with similar names in different directories.
In summary, using an absolute path with a forward slash at the beginning ensures that your program can consistently locate and load resources regardless of its execution context.
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
SLF4J (Simple Logging Facade for Java) is a logging framework that provides a simple and efficient way to log messages in Java applications. It serves as a facade or abstraction layer for various logging frameworks, allowing developers to switch between different logging implementations without changing their code.
One of the key benefits of SLF4J is its ability to decouple the application code from the underlying logging implementation. By using SLF4J, developers can write log statements using a common API, and then choose the desired logging framework at deployment time. This flexibility enables easy migration or integration with different logging systems based on specific requirements or preferences.
Providing information on how a program works through logging is highly beneficial for several reasons:
- Debugging and Troubleshooting: Logging allows developers to track the flow of execution, identify potential issues, and debug problems in real-time. By providing detailed information about the program's behavior, including variable values, method calls, and error messages, it becomes easier to pinpoint and fix bugs or unexpected behavior.
-
Monitoring and Performance Analysis: Logging can be used to monitor the performance of an application by capturing metrics such as response times, resource utilization, or database queries. This information helps in identifying bottlenecks or areas that require optimization.
-
Auditing and Compliance: In certain industries or applications where regulatory compliance is crucial (e.g., finance or healthcare), logging plays a vital role in auditing activities. By recording important events or actions within the program, it becomes possible to trace back any unauthorized access attempts or detect suspicious behavior.
-
Documentation and Communication: Logs serve as a form of documentation that captures the history of an application's execution. They provide insights into how different components interact with each other and help in understanding complex workflows. Additionally, logs can be shared with other team members or stakeholders to communicate issues, progress, or changes made during development.
In summary, SLF4J simplifies logging in Java applications by providing a unified API and decoupling the code from specific logging implementations. By leveraging logging, developers gain valuable insights into the program's behavior, enabling efficient debugging, performance analysis, compliance adherence, and effective communication within the development team.
There are several reasons why using SLF4J logging is preferred over print statements. Firstly, SLF4J provides a flexible and efficient logging framework that allows you to control the log output without modifying your code. This means that you can easily change the log level or redirect logs to different destinations (e.g., files, databases) without having to modify your codebase.
Secondly, SLF4J supports different logging implementations (e.g., Logback, Log4j) which allows you to choose the one that best suits your needs. This flexibility ensures that you can easily switch between logging frameworks without having to rewrite your code.
Additionally, SLF4J provides various logging levels (e.g., debug, info, error) which allow you to categorize and filter log messages based on their importance. This helps in troubleshooting and debugging as you can focus on relevant logs while ignoring less important ones.
Furthermore, using SLF4J promotes good coding practices by separating the concerns of logging and business logic. By using SLF4J's logger interface, you can write log statements with placeholders for variables or parameters, improving readability and maintainability of your code.
Lastly, SLF4J offers performance benefits over print statements. While print statements may introduce overhead due to I/O operations or string concatenation for constructing log messages, SLF4J's logging implementations are optimized for performance and provide efficient ways of handling log messages.
Overall, by using SLF4J logging instead of print statements, you gain flexibility in controlling log output, support for different logging frameworks, better organization of log messages with various levels, improved coding practices, and enhanced performance.
if you got a question just ask
oh no im just doing this for my write up ๐ญ
not copying but just taking ideas
btw does the bot use gpt4?
no
gpt3.5 smth smth
ahh
gpt-3.5-turbo
When you close the stage in JavaFX, the application window is closed and the program terminates. The close operation can be triggered by clicking on the close button (X) on the window or by calling the close() method on the stage object.
By default, closing the stage will also trigger an onCloseRequest event. You can handle this event to perform any necessary cleanup or save operations before closing the application.
If you have multiple stages in your application, closing one stage does not automatically close all other stages. Each stage needs to be closed individually.
In addition, if your JavaFX application is running as a standalone application (not embedded within another Java application), closing the main stage will terminate the entire Java Virtual Machine (JVM) and exit the program.
second prototype beginning soon ๐ช
package com.fluidity.program.ui;
public enum FluidUIAction {
// The different fluid actions and their string identifiers
PRIMARY_PAUSE("primary-pause"),
PRIMARY_STEP_FORWARD("primary-step-forward"),
PRIMARY_STEP_BACKWARD("primary-step-backward"),
SECONDARY_PAUSE("secondary-pause"),
SECONDARY_STEP_FORWARD("secondary-step-forward"),
SECONDARY_STEP_BACKWARD("secondary-step-backward");
private final String path;
FluidUIAction(String path) {
this.path = path;
}
public String getPath() {
return path;
}
// Returns the fluid action based off its path
public static FluidUIAction getByPath(String path) {
for (FluidUIAction action : FluidUIAction.values()) {
if (action.path.equals(path)) {
return action;
}
}
// Throws an exception if there is no action which has the path in the parameter
throw new IllegalArgumentException();
}
}```
Detected code, here are some useful tools:
What are the benefits of storing these actions as an enum?
first I wouldnt separate primary and secondary action
๐ญ
i cannot be bothered doing that rn tbh i just need to do the writeup i can probably change it after development stage
yeah ok then just ignore that for now
just this tbh
idk what i should write about it in my report ๐ญ
how would you do it differently?
you would likely use a String to identify it
which is bad, as it could easily lead to errors you will only notice at runtime
for example:
you identify an action like this:
"primary-pause"
and then have a typo or anything, it will compile like normal, because its still a valid string, but the program wont act normal
because it cant identify that action because it doesnt 100% equal the real action identified using strings
enum give you compile time safety
also enums are just kinda like normal objects but predefined
which makes sense here
because you already know beforehand which actions exists and you can define them through that enum
you have a clear set of named constants that represent the different actions
yeahh
this one is so cool
it's kinda just like an abstraction of the string stuff as well i guess
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
๐
I have taken a day and a bit off for this project
like i think i lost brain cells tryinig to develop that UI
The rest of this week is crazy ๐ญ
how much time you got for this?
for?
ah ok
P1 - Structure of main menu (done)
P2 - Interactivity of main menu (done but need to write up like maybe 1 more page not long left probably 90%)
P3 - Fluid Behaviour Implementation (90% done but need to write up)
P4 - Simulation loop and Simulation interactivity implementation (done but in AWT I just need to bring it to JFX)
P5 - Adding barriers to the fluid (not done)
P6 - Fluid Recording and backtracking (not done)
ok yeah mostly done already
yeahh
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
weeeeeeeeeeeeee
weeeeeee
is it possible if i could keep this channel open until I finish my project ๐ญ
not really
whyyyy
I'm not even lying i might have to take my laptop to the gym with me
i have so much writing to do
not even coding
WRITING
our bot doesnt support it ๐คทโโ๏ธ
and it wasnt needed before
but feel free to create a github issue and suggest it
or #server-suggestions
but yeah it wasnt needed before
ahh true
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
www
is it opened again?
where was the 1 week cooldown ๐ญ
anyways
sickness got onto me
been in bed for around 24 hours now
ofc i got up to do my stuff but
i am soooooo sick
doesn't stop the grind though ๐ช
im gonna finish the writing for prototype 2 today
hopefully i start prototype 3 tmrw
anyways
does anyone know how i can fake an error for file reading and writing ๐ญ
like something that sounds believable and not stupid
what happened to 1 week limit
wdym?
i need some file handling errors to fake and talk about
what are you using to read/write the files?
FileHandler class
thats your custom class
package com.fluidity.program.utilities;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class FileHandler {
private static Logger logger = LogManager.getLogger(FileHandler.class);
// Prevents the object from being created with the default constructor
private FileHandler() {
throw new UnsupportedOperationException("Utility Class");
}
public static boolean createFile(String name) {
try {
Path newFilePath = Paths.get(name);
Files.createFile(newFilePath);
} catch (IOException e) {
logger.error("Creating new file failed.", e);
return false;
}
return true;
}
public static List<String> readFile(String fileName) {
Path path = Path.of(fileName);
List<String> file = new ArrayList<>();
try {
file = Files.readAllLines(path);
} catch (IOException e) {
logger.error("Reading file failed.", e);
}
return file;
}
public static boolean writeLine(String fileName, String data) {
Path path = Path.of(fileName);
try {
Files.writeString(path, data);
} catch (IOException e) {
logger.error("Writing to file failed.", e);
return false;
}
return true;
}
public static boolean clearFile(String fileName) {
Path path = Path.of(fileName);
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
writer.write("");
writer.flush();
} catch (IOException e) {
logger.error("Writing to file failed.", e);
return false;
}
return true;
}
}
Detected code, here are some useful tools:
what uses it internal?
NIO
I would just look at the docs
to find out reasons it could fail
for example Files.createFile
or do you want to simulate a fail?
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
writer.write("");
writer.flush();
}
why not
try {
Files.writeString(path, data);
}
fake one, yes
i need to get marks ๐ญ
well
i do have an 'error' i got before
not sure if it counts as one though
it was basically
I had String[] configuration = line.split(":");
but i wanted to split only at the first colon
so i did String[] configuration = line.split(":", 1);
but it was meant to be 2
and how is that related?
im not sure if that's an error worth talking about
because all i had to do was simply change a number
ah so you need to talk about stuff that went wrong while creating the software?
yeahh
why do you parse config manually
fairss
not sure
oh are you taklkng about the yaml stuff
yeahh i think i said i didn't want to use extra stuff i think
my teacher doesn't like it either
?
that makes no sense in the real world
I hate it
also that is provided by java
its like not using arraylist
wdym you don't want to use extra stuff ?
like you don't want to use String because it's extra compared to char[] ?
๐ญ
yeah that's kinda what im doing lmao
i had to make my own linked list for the marks
and just to have all that extra logic in my program
who told you to create your own linked list?
did he really say you need to create your own linked list??? ๐
Ok this one is not the linked list one
i couldn't find it
but here is the one for the queue
he was talking about gaining marks
Am assuming you wrote the queue classes yourself
๐ญ
which is why i have to do a lot of the stuff manually
i did not send that wait
WTF
bruh
bruh
i think someones on my account
1 second
ok reset password
im chilling

what does that even mean ?
I think the teacher wants more files so he can give marks for more done, smth like that
ye
very giga mega tera peta yotta zotta kilo milli micro nano pico femto stupid
don't ask why i know that
we do too many conversions in physics
but if you already have a lot of classes, then there is no need to do that right ?
also don't use any linked list, they are bad
๐ญ๐ญ
fair enough
so if i am implementing a queue i should do so using an arraylist implementation?
well if i want a max number of elements I can do an array implementation of max size
Have you simulated the fluids yet
Just use ArrayDeque and don't recreate a list just for that
yes
it's a bit basic
and not in jfx
but in awt
i gotta chang eit to jfx
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
๐คท
๐ญ
lmao
our bot is not using discord timeout, should do tho
huh
need help converting this into jfx for a canvas
public synchronized void render(DataProvider pixelStream) {
BufferedImage imageContainer = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_BYTE_GRAY);
byte[] buffer = ((DataBufferByte) imageContainer.getRaster()
.getDataBuffer()).getData();
for (int y = 0; y < imageContainer.getHeight(); y++) {
for (int x = 0; x < imageContainer.getWidth(); x++) {
buffer[y * IMAGE_WIDTH + x] = pixelStream.provideData(x, y);
}
}
this.buffer = imageContainer;
repaint();
}```
Detected code, here are some useful tools:
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
what exactly should I be looking at?
you want to set individual pixels right?
then you either want to use an existent method like GraphicsContext#rect or similar or if you just want to set individual pixels you can use the PixelWriter provided by GraphicsContext#getPixelWriter and then set individual pixels:
https://openjfx.io/javadoc/21/javafx.graphics/javafx/scene/image/PixelWriter.html
my fluid is grayscale
what does pixelStream.provideData return?
I have this so far
PixelWriter pixelWriter = canvas.getGraphicsContext2D().getPixelWriter();
for (int y = 0; y < canvas.getHeight(); y++) {
for (int x = 0; x < canvas.getWidth(); x++) {
}
}```
Detected code, here are some useful tools:
a number from 0 to 255 representing what grayscale value I should plot
yeah then set all r, g, b to that same value and you get the grayscale as an RGB
so if pixelStream provideData at one location gives you 100 it will be:
R = 100
G = 100
B = 100
to give you a grayscale pixel
you now just need to use the setColor method
that is actually not needed
because there is Color#gray/Color#grayRgb
public synchronized void render(DataProvider<Byte> pixelStream) {
PixelWriter pixelWriter = canvas.getGraphicsContext2D()
.getPixelWriter();
for (int y = 0; y < canvas.getHeight(); y++) {
for (int x = 0; x < canvas.getWidth(); x++) {
pixelWriter.setColor(x, y, Color.grayRgb(pixelStream.provideData(x, y)));
}
}
}```
Detected code, here are some useful tools:
that should work right?
yeah
anyone good at conic sections here?
just ask your question directly
dont ask to ask
or ask if anyones around
just ask
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
yoo
yo
share your code
ahhh it' s aprivate rep hold on
I think i'm just going to redo this section it's very long and convoluted
why though?
it's going to be long for you to understand it and I haven't uploaded it onto github because i want to keep the previous version
becaysue this one doesn't work
you can point back to a previous commit in order to undo it
should i just make a new branch?
yeah tha would be better
going to check it later
just realised it has my email :/
imma send in dm if you don't mind
Whatโs wrong with that?
ohh
nice lmao
im still bad at the game lol
i can kinda wall to aerial
but not well
depends on the context
share the controller
do you modify the list while iterating?
no?
public class TestSimulationController extends Controller implements MouseAdapter {
@FXML
Canvas canvas;
Simulation simulation;
private boolean mouseHeld;
private List<FluidInput> sourceQueue;
private Instant startAdd;
private int[] previousCoords;
@Override
public void initialize(final URL url, final ResourceBundle resourceBundle) {
sourceQueue = new ArrayList<>();
startAdd = Instant.now();
simulation = new Simulation(this);
simulation.startSimulation();
}
@Override
@FXML
public void mousePressed(MouseEvent e) {
previousCoords = new int[] { (int) e.getX(), (int) e.getY() };
mouseHeld = true;
startAdd = Instant.now();
}
@Override
@FXML
public void mouseReleased() {
mouseHeld = false;
}
@Override
@FXML
public void mouseDragged(MouseEvent e) {
double velocityX = 0;
double velocityY = 0;
double dragScalar = 5.0;
if (previousCoords != null) {
velocityX = dragScalar * ((int) e.getX() - previousCoords[0]);
velocityY = dragScalar * ((int) e.getY() - previousCoords[1]);
}
startAdd = Instant.now();
previousCoords = new int[] { (int) e.getX(), (int) e.getY() };
sourceQueue.add(new FluidInput(previousCoords[0], previousCoords[1], velocityX, velocityY,
6.0 * hypot(velocityX, velocityY), simulation.CELL_LENGTH));
}
@Override
public synchronized void consumeSources(Consumer<FluidInput> sourceConsumer) {
if (mouseHeld) {
long timeHeld = Duration.between(startAdd, Instant.now())
.toMillis();
startAdd = Instant.now();
sourceQueue.add(
new FluidInput(previousCoords[0], previousCoords[1], 0, 0, timeHeld * 20, simulation.CELL_LENGTH));
}
for (FluidInput source : sourceQueue) {
sourceConsumer.accept(source);
}
sourceQueue.clear();
}
@Override
public synchronized void render(DataProvider pixelStream) {
PixelWriter pixelWriter = canvas.getGraphicsContext2D()
.getPixelWriter();
for (int y = 0; y < canvas.getHeight(); y++) {
for (int x = 0; x < canvas.getWidth(); x++) {
pixelWriter.setColor(x, y, Color.grayRgb(pixelStream.provideData(x, y)));
}
}
}
}```
you might be though
mouseDragged adds to sourceQueue. mouseDragged is called by the FX Thread
consumeSources is iterating over sourceDragged. consumeSources is called by thread-3
you aren't synchronizing the use of sourceQueue between those 2 threads. there's a good chance FX thread is adding while thread-3 is iterating
but I doubt using synchronization is a good idea for mouseDragged though
because it could block the fx thread
how can i fix that?
you'd use a synchronized collection, to make sure one thread waits for the other thread to finish using the list
though that introduces a new problem, as squid mentioned
if the list is long, the FX thread will have to wait a while for thread-3 to finish iterating
while the FX thread is waiting, your GUI will be unresponsive, since the FX thread handles all other GUI events, including rendering
@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
so each method would be synchronised?
Im so confused rn
@serene oak sorry for the ping but I remember you telling me something about this: What should I use when it comes to making a simulation in jfx, a custom game loop to split my update and render functionality or an animation timer?
I can't seem to find it
no idea and im out of context.
its always a good idea to split logic and rendering
so you're suggesting an animation timer wouldn't be the best idea?
no idea what ur referring to exactly
a grid based fluid simulation
new AnimationTimer() {
@Override
public void handle(long now) {
// rendering functionality
}
// ..
}
}.start();```
Detected code, here are some useful tools:
no idea what that class is
oh ok
i have no javafx experience and hence i dont respond to ur javafx specific questions
i think there was a problem in my game loop when i switched from awt to jfx
i cant tell u how to do animations in javafx
ahh okay
is creating scene based UI difficult in AWT?
because i've done the main simulation in it
you can first try to make the mouseDragged method to use synchronization, if you notice that it blocks fx thread heavily and thus the gui doesnt respond to other interactions in that time, you would need to use a different approach
like splitting the adding inside the mouseDragged method into another thread using ExecutorService and then make both usages synchronized
I have no idea if there is a better solution
yeah this is confusing ๐ญ
all this synchronization stuff
I just wanna quit the project atp why didn't i use awt
because javafx is better
not for simulations ๐ญ
what exactly is confusing?
it is
though a game engine is also a good fit for physics simulations
like in awt i can have a mouse adapter class
public class MouseAdapter extends java.awt.event.MouseAdapter {
private int[] previousCoords;
private boolean mouseHeld = false;
private List<FluidInput> sourceQueue;
private Instant startAdd;
public MouseAdapter() {
sourceQueue = new ArrayList<>(); //TALK ABOUT LINKED LIST
startAdd = Instant.now();
}
public void mousePressed(MouseEvent e) {
previousCoords = new int[] { e.getX(), e.getY() };
mouseHeld = true;
startAdd = Instant.now();
}
@Override
public void mouseReleased(MouseEvent e) {
mouseHeld = false;
}
public synchronized void mouseDragged(MouseEvent e) {
double velocityX = 0;
double velocityY = 0;
double dragScalar = 5.0;
if (previousCoords != null) {
velocityX = dragScalar * ((double) e.getX() - previousCoords[0]);
velocityY = dragScalar * ((double) e.getY() - previousCoords[1]);
}
startAdd = Instant.now();
previousCoords = new int[] { e.getX(), e.getY() };
sourceQueue.add(new FluidInput(previousCoords[0], previousCoords[1] - (30), velocityX, velocityY,
6.0 * hypot(velocityX, velocityY)));
}
synchronized void consumeSources(Consumer<FluidInput> sourceConsumer) {
if (mouseHeld) {
long timeHeld = Duration.between(startAdd, Instant.now())
.toMillis();
startAdd = Instant.now();
sourceQueue.add(new FluidInput(previousCoords[0], previousCoords[1], 0, 0, timeHeld * 20.0));
}
for (FluidInput source : sourceQueue) {
sourceConsumer.accept(source);
}
sourceQueue.clear();
}
}```
Detected code, here are some useful tools:
but in jfx my code is all messy cos it's all within 1 controller that impelments a bunch of interfaces
this only works because mouseDragged is synchronized
you can do the same thing in javafx
but ig might cause problems
thats yours to find out
i don't know how to deal with that in jfx ๐ญ
nioooooooooooo
have ytou seen my TestSimulationController
dont blindly synchronize methods. do you know how synchronized works?
using synchronized on a method is similar to doing synchronized(this)
if the methods belong to different objects, then the methods will synchronize on different locks
what would you suggest instead?
I thought about moving the adding inside the mouseDragged into a different thread as well and then synchronize both usages
but that sounds meh
that would be the right approach. don't do processing on the FX thread. if their mouseDragged became more complex, taking more time, they'd need to introduce a new thread either way
so having a worker thread to handle the processing of the event methods would be the approach
@grand garnet
yess i will look at it tmrw when i focus on the project again

@grand garnet
Your question has been closed due to inactivity.
If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.
Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.
When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.
Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.
With enough info, someone knows the answer for sure ๐
.
hi hi hellow
time to start some project work
ok yep im so cclose to giving up ๐ญ
I am so done for
why though
it isn't even rendering anything ๐ญ
OK NAH
bro
it works but when it is like very very small
why is it lagging so mucchhh
hard to tell without seeing code
oh
lemme upload it to github
there we go
i know it's not the actual fluid making everything lag because the same exact fluid class works with AWT
going to check it later
not without looking at it lol
oh ok lmaoo
I have a feeling it's about how often these are being called
ok
it works
but it is veryyy laggy
i updatd the master2 branch
yeah let me test some stuff
sure
just gonna state what i think it is
the FPS is too low that there are too many inputs being added
can you explain me how to use the simulation?
umm
so clicking on the screen at a point adds denisty to that point
dragging essentially adds density whilst also moving the density in a given direction
that's prety much it
doesnt work somehow
what cpu you got?
uh how is that related?
but amd ryzen 7 5800x3d
๐ญ

the scene im simply testing out the simulation on is the TEST_SIMULATION
im going to implement into UI later
but for me it doesn't run ๐ญ
like it's just veyr laggy
whereas awt is a lot smoother
these
the problem lies here
and I think I know why
you iterate with:
outer loop -> WIDTH
inner loop -> HEIGHT
but instead it should be
outer loop -> HEIGHT
inner loop -> WIDTH
pretty sure that doesn't matter because it's a 1D array?
i changed it and it still lags and crashes
mhmmm
pretty sure the Fluid isn't the problem
because it works fine in awt with the exact same implementation
i think it's to do with the mouse listening
is the thing on the left how long it takes to run?
hmm
so updating takes too long
public void update(double deltaTime) {
addSourcesFromUI();
fluid.step(deltaTime);
}```
Detected code, here are some useful tools:
public void update(double deltaTime) {
addSourcesFromUI();
fluid.step(deltaTime);
}
which one takes longer?
ok sorry ๐ญ
all good
ummm
bro ๐
no need to ping him
๐ญ
@Override
public synchronized void render(DataProvider pixelStream) {
GraphicsContext gc = canvas.getGraphicsContext2D();
PixelWriter pixelWriter = gc.getPixelWriter();
for (int y = 0; y < canvas.getHeight() ; y++) {
for (int x = 0; x < canvas.getWidth(); x++) {
byte pixelValue = pixelStream.provideData(x, y);
int color = pixelValue & 0xFF;
pixelWriter.setColor(x, y, Color.grayRgb(color));
}
}
}
this works a lot better for me
hmm
for me as well
so i should just use public void?
you have some memory leak
16gb ๐
time to find it out
would be a cool experience for you to learn about intellijs profiler
only using 133mb for me
even after spamming "fluid"?
like using the simulation lol
the problem why its crashing is because of memory
one problem I see is your step method
hmm
it creates multiple double array using size which in this case is 302 * 302
for me it seems like all of this can be fixed using streams
maybe
maybe not actually
damn
there must be a difference
most the memory problems are coming from this render method no?
ohh
i think i know why
is it because i am passing in the class as a parameter every single time
so it keeps settingit to a new parameter each time
but in which way is that a problem?
creating a new variable each time perhaps?
that doesnt case a problem
its weird because it looks more like an internal thing
for me it seems like its not clearing the old pixels
302 * 302 = 91204 pixels
no
how come
thats not how its supposed to be used
I just checked
the internal GraphicsContext uses some GrowableDataBuffer
so it seems like its not replacing bytes
but instead always appending
which lets me question the internal of javafx 
I am checking right now
@steep elbow you know smth about this? why is it storing all the pixels?
wot
?
mb
at some point the buffer should reset. GrowableDataBuffer is similar to ArrayList, where the buffer can grow as needed by a factor
how large is the image?
it's 300
what about your .fxml file though?
<AnchorPane prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.fluidity.program.ui.controllers.TestSimulationController">
<children>
<Canvas fx:id="canvas" height="400.0" onMouseDragged="#mouseDragged" onMousePressed="#mousePressed" onMouseReleased="#mouseReleased" width="400.0" />
</children>
</AnchorPane>
problems I can already tell:
- you call
renderfrom a different thread than the FX Thread - you always draw each pixel even though many didnt change
wdym by the FX thread?
all rendering happens on the fx thread
and if you do changes then you should also do that on the fx thread
my guess would be that changing the canvas from a different thread fucks up the clearing of the buffer somehow
let me try to create my own solution about the threading stuff
but thats going to take longer than just 10min
I probably wont even be able to finish it today, because I am gone later
also you should really make your simulation thread a daemon thread
or terminate it manually if someone closes the ui
otherwise the application continues running
what is the use of TPS btw?
ill take a look when i get home too
I am trying to fix it by letting the Simulation (drawing) extends AnimationTimer and then making another thread to handle all the calculation and updating the fluid stuff
the handle method provided by AnimationTimer is providing the delta time as an argument
and the handle method runs on the FX Thread
handled by javafx itself
ok I think I fixed it
it still uses a lot of memory because of Fluid.java which I didnt touch at all
but it doesnt crash
and doesnt lag
I am not sure about the synchronization of Fluid though
I dont know how to properly make a thread safe usage of the double array
dioxin might know
otherwise I think this is fine
also you might want to make the static variables CELL_LENGTH and FPS non static instead
just for the simplicity made them static
hope this helps
really need to go now
cant improve it further
@grand garnet @dense hare
you might dont even need to use another thread
and put everything into the handle of the AnimationTimer
but not sure how heavy the fluid calculations will be
I am not that much of a pro of concurrency and threading
like using synchronization might block the handle method anyways
so why not directly doing the fluid calculations inside the handle method
needs testing
and the calculation needs like 5ms or smth
which probably can be improved a lot
internally
back in like 3h
ok
i will have a look
but i had a cool brainy moment
why not combine the buffered image from awt with javafx?
and then use jfx for scene switching only
wdym
@grand garnet why can't you just fillRect on the graphics context ?
im ngl i don't know whta you mean lol
?
declaration: module: javafx.graphics, package: javafx.scene.canvas, class: GraphicsContext
look at its methods
it's the same as awt or swing
you can use it to draw stuff
so just draw rectangles
and i can still use the delta time I originally made?
There was some memory leak, my guess is that it was because he rendered from a different thread which isnโt allowed
this can't happen since javafx would prevent modification from another thread
?
You are really overcomplicating things
you just need to draw rect in a loop
that's all
ahh so instead of calculating for each pixel, I work out for one pixel and then apply to every cell
Not just like this, you would at least need threading or animation timer
And if you use threading you also need to use Platform.runLater for drawing
i am talking about the display aka what you are currently struggling with
The struggle wasnโt the displaying itself
But that there was a memory leak
Check the chat above
.
My guess is that the leak comes from threading
Because this code executed outside the fx thread
how does this look ala
@Override
public void render(DataProvider pixelStream) {
GraphicsContext gc = canvas.getGraphicsContext2D();
for (int y = 0; y < canvas.getHeight() ; y += pixelStream.getCellLength()) {
for (int x = 0; x < canvas.getWidth(); x += pixelStream.getCellLength()) {
byte pixelValue = pixelStream.provideData(x, y);
int color = pixelValue & 0xFF;
gc.setFill(Paint.valueOf(Color.grayRgb(color).toString()));
gc.fillRect(x, y, pixelStream.getCellLength(), pixelStream.getCellLength());
}
}
}
Detected code, here are some useful tools:
Why Paint.valueOf
Also this wonโt logically work
Because thatโs not what you want
wut
Try it out, idk
Your structure for the simulation is wrong in the first place
You would want to use AnimationTimer, the official non threaded way of a continuous loop (animation)
Itโs literally made for this
Let me further improve the code when I get home
how do i view memory capackty?
you shouldn't have any memory problem
what does this mean then?
oh
so do i have to do what squid said
because my simulation is running in this thread
private void startSimulationThread() {
simulationThread = new Thread(this);
simulationThread.start();
}
@Override
public void run() {
double deltaTimeSeconds = 1.0 / TPS;
double lastFrameTime = nanosToSeconds(System.nanoTime());
double secondsToConsume = 0.0;
while (simulationThread != null) {
double currentFrameTime = nanosToSeconds(System.nanoTime());
double lastFrameNeeded = currentFrameTime - lastFrameTime;
lastFrameTime = currentFrameTime;
secondsToConsume += lastFrameNeeded;
while (secondsToConsume >= deltaTimeSeconds) {
update(deltaTimeSeconds);
secondsToConsume -= deltaTimeSeconds;
}
render();
double currentFPS = 1.0 / lastFrameNeeded;
if (currentFPS > FPS) {
double targetSecondsPerFrame = 1.0 / FPS;
double secondsToWaste = Math.abs(targetSecondsPerFrame - lastFrameNeeded) / 1000000;
try {
TimeUnit.SECONDS.sleep(secondsToMillis(secondsToWaste));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}```
show render
it's a handler method within the same class:
public void render() {
mouseAdapter.render(this);
}```
within the mouse adapter:
```java
@Override
public void render(DataProvider pixelStream) {
GraphicsContext gc = canvas.getGraphicsContext2D();
for (int y = 0; y < canvas.getHeight() ; y += pixelStream.getCellLength()) {
for (int x = 0; x < canvas.getWidth(); x += pixelStream.getCellLength()) {
byte pixelValue = pixelStream.provideData(x, y);
int color = pixelValue & 0xFF;
gc.setFill(Color.grayRgb(color));
gc.fillRect(x, y, pixelStream.getCellLength(), pixelStream.getCellLength());
}
}
}```
Detected code, here are some useful tools:
its called in the run method (in a different thread)
where is the platform.runlater ?
this is definitelly wrong
cause concurrency problems
yeah but that wouldnt explain it entirely right?
I have no idea how javafx didn't detect that tho
thats what kinda confused me
normally javafx would detect that it is the wrong thread and crash
but it clearly runs in a different thread
maybe
concurrency problems can really mess up with everything
yeah true
so this is your priority to fix
I checked, canvas uses some growable data buffer internally
ig it couldnt properly clear it
because of concurrency problems
and thus it continued to grow and grow
and ended up filling my whole memory
in 10sec
and then crash
what's that ๐ญ
lemme check docs rq
wait
what should i search up ๐ญ
javafx is single threaded
that means that all UI stuff etc is handled on the FX Thread
and if you do UI stuff outside that it will break your javafx application
same for awt and swing
or any gui framework in any language btw
so what you have to do is simple
- copy the data to display
- call runlater
- display it
also, how are you storing the data to display ?
in an array
BRUH
size ?
i dropped my lego
(WIDTH+2)*(HEIGHT + 2)
I just get to 2 GB ram for 300x300 simulation
and it's a 1D array
which is ? 300x300 ?
why the +2 btw?
302x302
but the canvas is 300x300
dont ask me lol
and what's the datatype ?
double
so you dont have to calculate borders
@boreal socket the padding is for borders of the fluid
yea this is nothing to copy
so you can afford to array.clone() this
once per frame
I used this too when coding a game of life, that's some genious strats, there is no if(is within bounds)
the thing is he creates additional arrays each time step:
double[] u_prev = new double[size];
double[] v_prev = new double[size];
double[] dens_prev = new double[size];
// this 2 times (because project() is called twice)
double[] pressure = new double[size];
double[] divergenceField = new double[size];
seems like many arrays for this
I think you can improve here
but didnt look much into the logic yet
302 * 302 * 8 * 7 = 5 107 424
hm ok but thats like only 5 MB
not sure where the other ram stuff is coming from
going to look in a second
what are 8, 7 ?
7???
.
that's nothing tho
But yeah if that runs 30 times a second you end up with 150 MB
But still not really much
GC will kick in
Everything gone
why ?
do you copy the arrays each time ?
?
@boreal socket
but why are you saying that?
wdym
not like I am saying there will be 150 MB at once
????
this is the calculation for one time step
why are you saying
But yeah if that runs 30 times a second you end up with 150 MB
??
where does the 150MB come from ?
which 30 MB?
im still lost
5 MB per time step * 30 time steps per second will end up with 150 MB per second
but why do you multiply them ? do you copy them ?
they are just newly created arrays
ah
5mb?
but why doesn't it destroy these values
are they ever assigned to the fields ?
they are
I am just saying what gets created in one second
no it doesnt
you could go way faster
but I am wondering because I have 2 GB usage
???
and that code takes like 5ms per time step
let me have a look
no they are just local in the method
but there are additional 3 * 302 x 302 double arrays
as fields
then what's the point of those arrays ?
I D K
-_-
they are probably used for the simulation logic
it's for storing the densities and velocities before different fluid steps such as diffusion
fix the concurrency problems first
this.dt = deltaTime;
double[] u_prev = new double[size];
double[] v_prev = new double[size];
double[] dens_prev = new double[size];
diffuse(1, u_prev, u, viscosity);
diffuse(2, v_prev, v, viscosity);
project(u_prev, v_prev);
advect(1, u, u_prev, u_prev, v_prev);
advect(2, v, v_prev, u_prev, v_prev);
project(u, v);
diffuse(0, dens_prev, dens, diffusionRate);
advect(0, dens, dens_prev, u, v);
why don't you just ask here
i don't want to annoy you guys too much lmao
what's the point of this channel ?
I already gave the solution to that actually 
but got kinda ignored
well yea
- call runlater
- display it
i gave the solution
IM SORTRY
it's because
wait
basically
you know how my teacher
is very teachery
doesn't like me using all the fancy stuff

he wants me to make my own loop and everything like this
so, what's the data to display ?
for now it is density
using the standard provided javafx library is not fancy 
and I have an interface for which any class that implements it can provide that data
right, so first, clone it
Platform.runLater(() -> render(density.clone()));
it's basically as simple as this
you just do that
oh
and render only use density copy (and graphics context), nothing else
NOTHING
ELSE
in terms of this
im gonna have to somehow get this to my rendering class no?
wdym