Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ set(VariablesNodes_SOURCE_FILES)
set(ControlFlowNodes_SOURCE_FILES)

if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DVISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES")

# *************** EXECUTION_FLOW_NODES ***************
list(APPEND BaseExecutionFlowNodes_SOURCE_FILES
Expand Down Expand Up @@ -280,7 +279,10 @@ else()
add_library(VisualNodeSystem STATIC ${ALL_SOURCE_FILES})
endif()

target_include_directories(VisualNodeSystem PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/jsoncpp)
if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
#NOTE use cross platform method to set compile definitions
target_compile_definitions(VisualNodeSystem PRIVATE VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
endif()

source_group("Source Files" FILES ${VisualNodeSystem_SRC})
source_group("Source Files/SubSystems/VisualNodeArea/" FILES ${VisualNodeArea_SRC})
Expand All @@ -301,6 +303,7 @@ endif()
source_group("Source Files/ThirdParty/jsoncpp" FILES ${jsoncpp_SRC})

set(VISUAL_NODE_SYSTEM_THIRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty)
set(VISUAL_NODE_SYSTEM_THIRDPARTY_JSONCPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/jsoncpp)

# set the startup project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT VisualNodeSystem)
Expand Down Expand Up @@ -336,6 +339,7 @@ endif()
include_directories(
${DEAR_IMGUI_INCLUDE_DIR}
${VISUAL_NODE_SYSTEM_THIRDPARTY_DIR}
${VISUAL_NODE_SYSTEM_THIRDPARTY_JSONCPP_DIR}
)

set(VISUAL_NODE_SYSTEM_THIRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty PARENT_SCOPE)
Expand All @@ -353,4 +357,4 @@ add_custom_target(VisualNodeSystemPreBuild
${CMAKE_CURRENT_SOURCE_DIR}/VersionInfo/VISUAL_NODE_SYSTEM_Version.h
)

add_dependencies(VisualNodeSystem VisualNodeSystemPreBuild)
add_dependencies(VisualNodeSystem VisualNodeSystemPreBuild)
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,93 @@ bool BaseArithmeticOperatorNode::CanConnect(NodeSocket* OwnSocket, NodeSocket* C
}

return true;
}
}

void BaseArithmeticOperatorNode::Execute()
{
// Both A and B input sockets are required to perform the operation.
if (Input.size() <= 2)
return;

std::string CurrentMode = GetActiveINDataType();
if (CurrentMode.empty())
return;

// If we don't have both A and B inputs connected, we can't do anything.
if (Input[1]->GetConnectedSockets().empty() &&
Input[2]->GetConnectedSockets().empty())
return;

void* AData = nullptr;
if (!Input[1]->GetConnectedSockets().empty())
AData = Input[1]->GetConnectedSockets()[0]->GetData();

void* BData = nullptr;
if (!Input[2]->GetConnectedSockets().empty())
BData = Input[2]->GetConnectedSockets()[0]->GetData();

if (AData == nullptr && BData == nullptr)
return;

// Call the appropriate operation method based on the data type.
if (CurrentMode == "INT")
{
int A = 0;
if (AData != nullptr)
A = *reinterpret_cast<int*>(AData);

int B = 0;
if (BData != nullptr)
B = *reinterpret_cast<int*>(BData);

LocalIntegerData = PerformOperation(A, B);
}
else if (CurrentMode == "FLOAT")
{
float A = 0.0f;
if (AData != nullptr)
A = *reinterpret_cast<float*>(AData);

float B = 0.0f;
if (BData != nullptr)
B = *reinterpret_cast<float*>(BData);

LocalFloatData = PerformOperation(A, B);
}
else if (CurrentMode == "VEC2")
{
glm::vec2 A = glm::vec2(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec2*>(AData);

glm::vec2 B = glm::vec2(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec2*>(BData);

LocalVec2Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC3")
{
glm::vec3 A = glm::vec3(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec3*>(AData);

glm::vec3 B = glm::vec3(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec3*>(BData);

LocalVec3Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC4")
{
glm::vec4 A = glm::vec4(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec4*>(AData);

glm::vec4 B = glm::vec4(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec4*>(BData);

LocalVec4Data = PerformOperation(A, B);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,169 +59,7 @@ class BaseArithmeticOperatorNode : public BaseExecutionFlowNode
}
}

// Specialization for integer type.
template <>
int PerformOperation<int>(const int& A, const int& B)
{
switch (OperatorType)
{
case ArithmeticOperationType::ADD:
return A + B;
case ArithmeticOperationType::SUBTRACT:
return A - B;
case ArithmeticOperationType::MULTIPLY:
return A * B;
case ArithmeticOperationType::DIVIDE:
{
if (B == 0)
return A;
if (A == INT_MIN && B == -1)
return INT_MAX; // INT_MIN / -1 overflows int; saturate like the POWER case.
return A / B;
}
case ArithmeticOperationType::MODULUS:
{
if (B == 0)
return A;
if (A == INT_MIN && B == -1)
return 0; // INT_MIN % -1 is mathematically 0.
return A % B;
}
case ArithmeticOperationType::POWER:
{
const double Result = std::pow(static_cast<double>(A), static_cast<double>(B));

if (!std::isfinite(Result))
return 0;

if (Result >= static_cast<double>(INT_MAX))
return INT_MAX;

if (Result <= static_cast<double>(INT_MIN))
return INT_MIN;

return static_cast<int>(Result);
}
default:
return A;
}
}

// Specialization for floating-point type
template <>
float PerformOperation<float>(const float& A, const float& B)
{
switch (OperatorType)
{
case ArithmeticOperationType::ADD:
return A + B;
case ArithmeticOperationType::SUBTRACT:
return A - B;
case ArithmeticOperationType::MULTIPLY:
return A * B;
case ArithmeticOperationType::DIVIDE:
if (B == 0.0f)
return A;
return A / B;
case ArithmeticOperationType::POWER:
return std::pow(A, B);
case ArithmeticOperationType::MODULUS:
if (B == 0.0f)
return A;
return std::fmod(A, B);
default:
return A;
}
}

void Execute()
{
// Both A and B input sockets are required to perform the operation.
if (Input.size() <= 2)
return;

std::string CurrentMode = GetActiveINDataType();
if (CurrentMode.empty())
return;

// If we don't have both A and B inputs connected, we can't do anything.
if (Input[1]->GetConnectedSockets().empty() &&
Input[2]->GetConnectedSockets().empty())
return;

void* AData = nullptr;
if (!Input[1]->GetConnectedSockets().empty())
AData = Input[1]->GetConnectedSockets()[0]->GetData();

void* BData = nullptr;
if (!Input[2]->GetConnectedSockets().empty())
BData = Input[2]->GetConnectedSockets()[0]->GetData();

if (AData == nullptr && BData == nullptr)
return;

// Call the appropriate operation method based on the data type.
if (CurrentMode == "INT")
{
int A = 0;
if (AData != nullptr)
A = *reinterpret_cast<int*>(AData);

int B = 0;
if (BData != nullptr)
B = *reinterpret_cast<int*>(BData);

LocalIntegerData = PerformOperation(A, B);
}
else if (CurrentMode == "FLOAT")
{
float A = 0.0f;
if (AData != nullptr)
A = *reinterpret_cast<float*>(AData);

float B = 0.0f;
if (BData != nullptr)
B = *reinterpret_cast<float*>(BData);

LocalFloatData = PerformOperation(A, B);
}
else if (CurrentMode == "VEC2")
{
glm::vec2 A = glm::vec2(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec2*>(AData);

glm::vec2 B = glm::vec2(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec2*>(BData);

LocalVec2Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC3")
{
glm::vec3 A = glm::vec3(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec3*>(AData);

glm::vec3 B = glm::vec3(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec3*>(BData);

LocalVec3Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC4")
{
glm::vec4 A = glm::vec4(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec4*>(AData);

glm::vec4 B = glm::vec4(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec4*>(BData);

LocalVec4Data = PerformOperation(A, B);
}
}
void Execute();

std::function<void* ()> ResultDataGetter = [this]() -> void* {
std::string CurrentMode = GetActiveINDataType();
Expand Down Expand Up @@ -263,4 +101,79 @@ class BaseArithmeticOperatorNode : public BaseExecutionFlowNode
void Draw();

std::string GetActiveINDataType();
};
};

// Specialization for integer type.
template <>
inline int BaseArithmeticOperatorNode::PerformOperation<int>(const int& A, const int& B)
{
switch (OperatorType)
{
case ArithmeticOperationType::ADD:
return A + B;
case ArithmeticOperationType::SUBTRACT:
return A - B;
case ArithmeticOperationType::MULTIPLY:
return A * B;
case ArithmeticOperationType::DIVIDE:
{
if (B == 0)
return A;
if (A == INT_MIN && B == -1)
return INT_MAX; // INT_MIN / -1 overflows int; saturate like the POWER case.
return A / B;
}
case ArithmeticOperationType::MODULUS:
{
if (B == 0)
return A;
if (A == INT_MIN && B == -1)
return 0; // INT_MIN % -1 is mathematically 0.
return A % B;
}
case ArithmeticOperationType::POWER:
{
const double Result = std::pow(static_cast<double>(A), static_cast<double>(B));

if (!std::isfinite(Result))
return 0;

if (Result >= static_cast<double>(INT_MAX))
return INT_MAX;

if (Result <= static_cast<double>(INT_MIN))
return INT_MIN;

return static_cast<int>(Result);
}
default:
return A;
}
}

// Specialization for floating-point type
template <>
inline float BaseArithmeticOperatorNode::PerformOperation<float>(const float& A, const float& B)
{
switch (OperatorType)
{
case ArithmeticOperationType::ADD:
return A + B;
case ArithmeticOperationType::SUBTRACT:
return A - B;
case ArithmeticOperationType::MULTIPLY:
return A * B;
case ArithmeticOperationType::DIVIDE:
if (B == 0.0f)
return A;
return A / B;
case ArithmeticOperationType::POWER:
return std::pow(A, B);
case ArithmeticOperationType::MODULUS:
if (B == 0.0f)
return A;
return std::fmod(A, B);
default:
return A;
}
}
Loading
Loading