diff --git a/src/OpDefs/CMakeLists.txt b/src/OpDefs/CMakeLists.txt index 4233ea1..aa335f6 100644 --- a/src/OpDefs/CMakeLists.txt +++ b/src/OpDefs/CMakeLists.txt @@ -28,6 +28,7 @@ add_library(${libName} SHARED GopGeometryImport.cpp GopGrid.cpp GopSineWave.cpp + GopOceanSurface.cpp ) target_link_libraries(${libName} PRIVATE Qt6::Core Qt6::Widgets Qt6::SvgWidgets Qt6::OpenGLWidgets glm::glm Eigen3::Eigen TBB::tbb) diff --git a/src/OpDefs/GopOceanSurface.cpp b/src/OpDefs/GopOceanSurface.cpp new file mode 100644 index 0000000..487d280 --- /dev/null +++ b/src/OpDefs/GopOceanSurface.cpp @@ -0,0 +1,141 @@ +#include "OpDefs/GopOceanSurface.h" +#include "Engine/Parameter/Range.h" +#include "Engine/Types.h" +#include +#include +#include +#include +#include +#include +#include + +GopOceanSurface::GopOceanSurface(enzo::nt::NetworkManager* network, enzo::op::OpInfo opInfo) +: GeometryOpDef(network, opInfo) +{ + +} + +void GopOceanSurface::cookOp(enzo::op::Context context) +{ + using namespace enzo; + + if(outputRequested(0)) + { + geo::Geometry geo = context.cloneInputGeo(0); + + const ga::Offset pointCount = geo.getNumPoints(); + + tbb::parallel_for(tbb::blocked_range(0, pointCount), [this, &geo](tbb::blocked_range range){ + for(ga::Offset i=range.begin(); i!=range.end(); ++i) + { + bt::Vector3 pos = geo.getPointPos(i); + + pos = getSurfacePos(pos); + + geo.setPointPos(i, pos); + } + }); + + setOutputGeometry(0, geo); + } + +} + +enzo::bt::Vector3 GopOceanSurface::getSurfacePos(const enzo::bt::Vector3 pos) +{ + using enzo::bt::Vector3; + + const int waveNum = 30; + const int waveDirNum = 20; + + const float speed = 1.0f; + const float frame = 0.0f; + const float t = speed * frame; + + float x = 0.0f; + float y = 0.0f; + + float baseWaveLength = 2.0f; + float baseAmp = 0.005f; + + const float offsetForEachDir = 20.8f; + + float offset = 17.2f; + + Vector3 outDisplacement(0.0f, 0.0f, 0.0f); + + for (int i = 0; i < waveDirNum; ++i) { + float angle = (float(i) / float(waveDirNum)) * 2.0f * float(M_PI); + Vector3 dir(std::cos(angle), 0.0f, std::sin(angle)); + + float dirOffset = 20.0f; + float offset = (float(i) * dirOffset) * 0.1f + offsetForEachDir; + + float a = pos.dot(dir); + + for (int j = 0; j < waveNum; ++j) { + float waveLength = baseWaveLength / (float(j) + 1.0f); + float amplitude = baseAmp / (float(j) + 1.0f); + offset += (float(j) + 826.0f) * 0.001f; + + float k = 2.0f * float(M_PI) / waveLength; + float theta = k * a + t + offset; + + x = amplitude * std::sin(theta); + y -= amplitude * std::cos(theta); + outDisplacement += Vector3(x * dir.x(), 0.0f, x * dir.z()); + } + } + + // big waves + for (int i = 0; i < 5; ++i) + { + float bigWaveAngle = 0.75f * 2.0f * float(M_PI); + float bigWaveStretch = 0.01f; + Vector3 bigWaveDir(std::cos(bigWaveAngle) * bigWaveStretch, 1.0f, std::sin(bigWaveAngle) * bigWaveStretch); + + int bigWaveNum = 3; + Vector3 bigWaveMaskPos = pos; + bigWaveMaskPos += Vector3(100.0f * float(238 + i), 100.0f * float(238 + i), 100.0f * float(238 + i)); + // change frequency of noise + bigWaveMaskPos = Vector3(bigWaveMaskPos.x() * 0.03f, bigWaveMaskPos.y() * 0.03f, bigWaveMaskPos.z() * 0.03f); + float bigWaveMask = 1.0f; + // bigWaveMask = 1; + + float angleVariation = 0.1f; + float angle = (0.5f + float(i) * angleVariation) * 2.0f * float(M_PI); + Vector3 dir(std::cos(angle), 0.0f, std::sin(angle)); + + float dirOffset = 20.0f; + offset = 6072.0f * 0.01f * dirOffset; + + float a = pos.dot(dir); + + baseWaveLength = 30.0f; + baseAmp = 0.2f; + + for (int j = 0; j < bigWaveNum; ++j) { + float waveLength = baseWaveLength / (float(j) + 1.0f); + float amplitude = baseAmp / (float(j) + 1.0f); + offset += (float(j) + 826.0f) * 0.005f; + + float k = 2.0f * float(M_PI) / waveLength; + float theta = k * a + t + offset; + + x = amplitude * std::sin(theta); + y -= amplitude * std::cos(theta) * bigWaveMask; + outDisplacement += Vector3(x * dir.x(), 0.0f, x * dir.z()); + } + } + outDisplacement = Vector3(outDisplacement.x(), y, outDisplacement.z()); + + return Vector3(pos.x() + outDisplacement.x(), + pos.y() + outDisplacement.y(), + pos.z() + outDisplacement.z()); +} + + +enzo::prm::Template GopOceanSurface::parameterList[] = +{ + enzo::prm::Terminator +}; diff --git a/src/OpDefs/GopOceanSurface.h b/src/OpDefs/GopOceanSurface.h new file mode 100644 index 0000000..c9584b3 --- /dev/null +++ b/src/OpDefs/GopOceanSurface.h @@ -0,0 +1,20 @@ +#pragma once +#include "Engine/Operator/GeometryOpDef.h" +#include "Engine/Parameter/Template.h" +#include "Engine/Types.h" + +class GopOceanSurface +: public enzo::nt::GeometryOpDef +{ +public: + GopOceanSurface(enzo::nt::NetworkManager* network, enzo::op::OpInfo opInfo); + virtual void cookOp(enzo::op::Context context); + enzo::bt::Vector3 getSurfacePos(const enzo::bt::Vector3 pos); + static enzo::nt::GeometryOpDef* ctor(enzo::nt::NetworkManager* network, enzo::op::OpInfo opInfo) + { + return new GopOceanSurface(network, opInfo); + } + + static BOOST_SYMBOL_EXPORT enzo::prm::Template parameterList[]; + +}; diff --git a/src/OpDefs/RegisterPlugin.cpp b/src/OpDefs/RegisterPlugin.cpp index 2d84435..431baab 100644 --- a/src/OpDefs/RegisterPlugin.cpp +++ b/src/OpDefs/RegisterPlugin.cpp @@ -2,6 +2,7 @@ #include "Engine/Operator/OperatorTable.h" #include "GopGeometryImport.h" #include "GopHouse.h" +#include "GopOceanSurface.h" #include "GopTestCube.h" #include "OpDefs/GopTransform.hpp" #include "OpDefs/GopGrid.h" @@ -79,6 +80,17 @@ extern "C" 1, } ); + addOperator( + enzo::op::OpInfo { + "oceanSurface", + "Ocean Surface", + &GopOceanSurface::ctor, + GopOceanSurface::parameterList, + 1, + 1, + 1, + } + ); } }