diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt index 07d5e231c..b20262897 100644 --- a/android/CMakeLists.txt +++ b/android/CMakeLists.txt @@ -57,14 +57,16 @@ include_directories(../bridging/android/jni/graphics/shader) include_directories(../bridging/android/jni/map) include_directories(../bridging/android/jni/map/controls) include_directories(../bridging/android/jni/map/layers) +include_directories(../bridging/android/jni/map/layers/effect) +include_directories(../bridging/android/jni/map/layers/icon) +include_directories(../bridging/android/jni/map/layers/line) include_directories(../bridging/android/jni/map/layers/objects) +include_directories(../bridging/android/jni/map/layers/polygon) +include_directories(../bridging/android/jni/map/layers/skysphere) +include_directories(../bridging/android/jni/map/layers/text) include_directories(../bridging/android/jni/map/layers/tiled) include_directories(../bridging/android/jni/map/layers/tiled/raster) include_directories(../bridging/android/jni/map/layers/tiled/vector) -include_directories(../bridging/android/jni/map/layers/polygon) -include_directories(../bridging/android/jni/map/layers/icon) -include_directories(../bridging/android/jni/map/layers/line) -include_directories(../bridging/android/jni/map/layers/text) include_directories(../bridging/android/jni/map/loader) include_directories(../bridging/android/jni/map/scheduling) include_directories(../bridging/android/jni/map/coordinates) @@ -81,7 +83,13 @@ include_directories(../shared/src/map/camera) include_directories(../shared/src/map/controls) include_directories(../shared/src/map/coordinates) include_directories(../shared/src/map/layers) +include_directories(../shared/src/map/layers/effect) +include_directories(../shared/src/map/layers/icon) include_directories(../shared/src/map/layers/objects) +include_directories(../shared/src/map/layers/polygon) +include_directories(../shared/src/map/layers/line) +include_directories(../shared/src/map/layers/skysphere) +include_directories(../shared/src/map/layers/text) include_directories(../shared/src/map/layers/tiled) include_directories(../shared/src/map/layers/tiled/raster) include_directories(../shared/src/map/layers/tiled/wmts) @@ -102,10 +110,6 @@ include_directories(../shared/src/map/layers/tiled/vector/sublayers/background) include_directories(../shared/src/map/layers/tiled/vector/symbol) include_directories(../shared/src/map/layers/tiled/vector/description) include_directories(../shared/src/map/layers/tiled/vector/parsing) -include_directories(../shared/src/map/layers/polygon) -include_directories(../shared/src/map/layers/icon) -include_directories(../shared/src/map/layers/line) -include_directories(../shared/src/map/layers/text) include_directories(../shared/src/map/scheduling) include_directories(../shared/src/utils) include_directories(src/main/cpp) diff --git a/android/src/main/cpp/graphics/objects/Quad2dOpenGl.cpp b/android/src/main/cpp/graphics/objects/Quad2dOpenGl.cpp index 0b2639198..6205a5d6c 100644 --- a/android/src/main/cpp/graphics/objects/Quad2dOpenGl.cpp +++ b/android/src/main/cpp/graphics/objects/Quad2dOpenGl.cpp @@ -37,13 +37,13 @@ void Quad2dOpenGl::clear() { void Quad2dOpenGl::setIsInverseMasked(bool inversed) { isMaskInversed = inversed; } -void Quad2dOpenGl::setFrame(const Quad3dD &frame, const RectD &textureCoordinates, const Vec3D &origin, bool is3D) { +void Quad2dOpenGl::setFrame(const Quad3dD &frame, const RectD &textureCoordinates, const Vec3D &origin, bool is3d) { std::lock_guard lock(dataMutex); ready = false; this->frame = frame; this->textureCoordinates = textureCoordinates; this->quadOrigin = origin; - this->is3D = is3D; + this->is3d = is3d; } void Quad2dOpenGl::setSubdivisionFactor(int32_t factor) { @@ -79,7 +79,7 @@ void Quad2dOpenGl::computeGeometry(bool texCoordsOnly) { // Data mutex covered by caller Quad2dOpenGL::setup() if (subdivisionFactor == 0) { if (!texCoordsOnly) { - if (is3D) { + if (is3d) { vertices = { (float) (1.0 * std::sin(frame.topLeft.y) * std::cos(frame.topLeft.x) - quadOrigin.x), (float) (1.0 * cos(frame.topLeft.y) - quadOrigin.y), @@ -152,8 +152,8 @@ void Quad2dOpenGl::computeGeometry(bool texCoordsOnly) { if (!texCoordsOnly) { double x = originX + deltaDX; double y = originY + deltaDY; - double z = is3D ? originZ + deltaDZ : 0.0; - if (is3D) { + double z = is3d ? originZ + deltaDZ : 0.0; + if (is3d) { vertices.push_back((float) (1.0 * std::sin(y) * std::cos(x) - quadOrigin.x)); vertices.push_back((float) (1.0 * cos(y) - quadOrigin.y)); vertices.push_back((float) (-1.0 * std::sin(x) * std::sin(y) - quadOrigin.z)); @@ -206,6 +206,8 @@ void Quad2dOpenGl::prepareGlData(int program) { vpMatrixHandle = glGetUniformLocation(program, "uvpMatrix"); mMatrixHandle = glGetUniformLocation(program, "umMatrix"); originOffsetHandle = glGetUniformLocation(program, "uOriginOffset"); + originHandle = glGetUniformLocation(program, "uOrigin"); + glDataBuffersGenerated = true; } @@ -289,7 +291,7 @@ void Quad2dOpenGl::renderAsMask(const std::shared_ptr<::RenderingContextInterfac render(context, renderPass, vpMatrix, mMatrix, origin, false, screenPixelAsRealMeterFactor); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } - +#include "Logger.h" void Quad2dOpenGl::render(const std::shared_ptr<::RenderingContextInterface> &context, const RenderPassConfig &renderPass, int64_t vpMatrix, int64_t mMatrix, const ::Vec3D &origin, bool isMasked, double screenPixelAsRealMeterFactor) { @@ -337,6 +339,9 @@ void Quad2dOpenGl::render(const std::shared_ptr<::RenderingContextInterface> &co glUniformMatrix4fv(vpMatrixHandle, 1, false, (GLfloat *)vpMatrix); glUniformMatrix4fv(mMatrixHandle, 1, false, (GLfloat *)mMatrix); glUniform4f(originOffsetHandle, quadOrigin.x - origin.x, quadOrigin.y - origin.y, quadOrigin.z - origin.z, 0.0); + if (originHandle >= 0) { + glUniform4f(originHandle, origin.x, origin.y, origin.z, 1.0); + } // Draw the triangles glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); diff --git a/android/src/main/cpp/graphics/objects/Quad2dOpenGl.h b/android/src/main/cpp/graphics/objects/Quad2dOpenGl.h index 6e7662eac..318305f3e 100644 --- a/android/src/main/cpp/graphics/objects/Quad2dOpenGl.h +++ b/android/src/main/cpp/graphics/objects/Quad2dOpenGl.h @@ -78,6 +78,7 @@ class Quad2dOpenGl : public GraphicsObjectInterface, int vpMatrixHandle; int mMatrixHandle; int originOffsetHandle; + int originHandle; int positionHandle; GLuint vertexBuffer; std::vector vertices; @@ -87,7 +88,7 @@ class Quad2dOpenGl : public GraphicsObjectInterface, GLuint indexBuffer; std::vector indices; Vec3D quadOrigin = Vec3D(0.0, 0.0, 0.0); - bool is3D = false; + bool is3d = false; std::shared_ptr textureHolder; int texturePointer; diff --git a/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.cpp b/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.cpp index 24b6a9eb3..4c39609d9 100644 --- a/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.cpp +++ b/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.cpp @@ -23,6 +23,7 @@ #include "StretchInstancedShaderOpenGl.h" #include "IcosahedronColorShaderOpenGl.h" #include "SphereEffectShaderOpenGl.h" +#include "SkySphereShaderOpenGl.h" std::shared_ptr ShaderFactoryOpenGl::createAlphaShader() { return std::make_shared(false); @@ -109,3 +110,7 @@ std::shared_ptr ShaderFactoryOpenGl::createIcosahedronColo std::shared_ptr ShaderFactoryOpenGl::createSphereEffectShader() { return std::make_shared(); } + +std::shared_ptr ShaderFactoryOpenGl::createSkySphereShader() { + return std::make_shared(); +} diff --git a/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.h b/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.h index 3b14904fa..c34233f84 100644 --- a/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.h +++ b/android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.h @@ -56,4 +56,6 @@ class ShaderFactoryOpenGl : public ShaderFactoryInterface { std::shared_ptr createIcosahedronColorShader() override; std::shared_ptr createSphereEffectShader() override; + + std::shared_ptr createSkySphereShader() override; }; diff --git a/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.cpp b/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.cpp new file mode 100644 index 000000000..7c67b28d5 --- /dev/null +++ b/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +#include "SkySphereShaderOpenGl.h" +#include "OpenGlContext.h" + +const std::string SkySphereShaderOpenGl::programName = "UBMAP_SkySphereShaderOpenGl"; + +std::string SkySphereShaderOpenGl::getProgramName() { + return programName; +} + +void SkySphereShaderOpenGl::setupProgram(const std::shared_ptr<::RenderingContextInterface> &context) { + std::shared_ptr openGlContext = std::static_pointer_cast(context); + // prepare shaders and OpenGL program + int vertexShader = loadShader(GL_VERTEX_SHADER, getVertexShader()); + int fragmentShader = loadShader(GL_FRAGMENT_SHADER, getFragmentShader()); + + int program = glCreateProgram(); // create empty OpenGL Program + glAttachShader(program, vertexShader); // add the vertex shader to program + glDeleteShader(vertexShader); + glAttachShader(program, fragmentShader); // add the fragment shader to program + glDeleteShader(fragmentShader); + + glLinkProgram(program); // create OpenGL program executables + + openGlContext->storeProgram(programName, program); + + inverseVPMatrixHandle = glGetUniformLocation(program, "uInverseVPMatrix"); + cameraPositionHandle = glGetUniformLocation(program, "uCameraPosition"); +} + +std::shared_ptr SkySphereShaderOpenGl::asShaderProgramInterface() { + return shared_from_this(); +} + +void SkySphereShaderOpenGl::setCameraProperties(const std::vector &inverseVP, + const Vec3D &cameraPosition) { + std::lock_guard lock(dataMutex); + this->inverseVPMatrix = inverseVP; + this->cameraPosition = cameraPosition; +} + +void SkySphereShaderOpenGl::preRender(const std::shared_ptr<::RenderingContextInterface> &context) { + BaseShaderProgramOpenGl::preRender(context); + { + std::lock_guard lock(dataMutex); + glUniformMatrix4fv(inverseVPMatrixHandle, 1, false, (GLfloat *)inverseVPMatrix.data()); + glUniform4f(cameraPositionHandle, cameraPosition.x, cameraPosition.y, cameraPosition.z, 1.0); + } +} + +std::string SkySphereShaderOpenGl::getVertexShader() { + return OMMVersionedGlesShaderCode(320 es, + uniform mat4 uvpMatrix; + uniform mat4 umMatrix; + in vec4 vPosition; + in vec2 texCoordinate; + out vec2 v_screenPos; + + void main() { + gl_Position = vPosition; // in screen coordinates + v_screenPos = texCoordinate; + } + ); +} + +std::string SkySphereShaderOpenGl::getFragmentShader() { + return OMMVersionedGlesShaderCode(320 es, + precision mediump float; + uniform vec4 uOriginOffset; + uniform vec4 uOrigin; + uniform vec4 uCameraPosition; + uniform mat4 uInverseVPMatrix; + uniform sampler2D textureSampler; + + in vec2 v_screenPos; + out vec4 fragmentColor; + + const float PI = 3.1415926536; + + void main() { + vec4 posCart = uInverseVPMatrix * vec4(v_screenPos.x, -v_screenPos.y, 1.0, 1.0); + posCart /= posCart.w; + + // Assume the sky on a sphere around the camera (and not the earth's center) + vec4 dirCamera = normalize(posCart - uCameraPosition); + + float rasc = atan(dirCamera.z, dirCamera.x) + PI; + float decl = asin(dirCamera.y); + + vec2 texCoords = vec2( + -(rasc / (2.0 * PI)) + 1.0, + -decl / PI + 0.5 + ); + + ivec2 textureSize = textureSize(textureSampler, 0); + vec2 size = vec2(1.0 / float(textureSize.x), 1.0 / float(textureSize.y)); + size.y *= cos(decl); + + // Mutli-sampling + /*fragmentColor = 0.2837 * texture(textureSampler, texCoords); + fragmentColor = fragmentColor + 0.179083648 * texture(textureSampler, texCoords + (vec2(0.0, -2.0)) * size); + fragmentColor = fragmentColor + 0.179083648 * texture(textureSampler, texCoords + (vec2(2.0, 0.0)) * size); + fragmentColor = fragmentColor + 0.179083648 * texture(textureSampler, texCoords + (vec2(0.0, 2.0)) * size); + fragmentColor = fragmentColor + 0.179083648 * texture(textureSampler, texCoords + (vec2(-2.0, 0.0)) * size);*/ + + // Single sample + fragmentColor = texture(textureSampler, texCoords); + + /*if (abs(mod(texCoords.x, 0.125)) < 0.001) { + fragmentColor = vec4(0.0, 0.0, 1.0, 1.0); + } else if (abs(mod(texCoords.y, 0.125)) < 0.001) { + fragmentColor = vec4(0.0, 1.0, 1.0, 1.0); + }*/ /*else { + fragmentColor = vec4(texCoords, 0.0, 1.0); + }*/ + + } + ); +} diff --git a/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.h b/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.h new file mode 100644 index 000000000..053496d4a --- /dev/null +++ b/android/src/main/cpp/graphics/shader/SkySphereShaderOpenGl.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +#pragma once + +#include "BaseShaderProgramOpenGl.h" +#include "SkySphereShaderInterface.h" + +class SkySphereShaderOpenGl + : public BaseShaderProgramOpenGl, + public SkySphereShaderInterface, + public std::enable_shared_from_this { +public: + std::string getProgramName() override; + + void setupProgram(const std::shared_ptr<::RenderingContextInterface> &context) override; + + std::shared_ptr asShaderProgramInterface() override; + + void setCameraProperties(const std::vector &inverseVP, const Vec3D &cameraPosition) override; + + void preRender(const std::shared_ptr<::RenderingContextInterface> &context) override; + + std::string getVertexShader() override; + +protected: + std::string getFragmentShader() override; + +private: + const static std::string programName; + + std::mutex dataMutex; + std::vector inverseVPMatrix = {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}; + Vec3D cameraPosition = {0.0, 0.0, 0.0}; + GLint inverseVPMatrixHandle; + GLint cameraPositionHandle; +}; diff --git a/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/ShaderFactoryInterface.kt b/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/ShaderFactoryInterface.kt index fac087124..5e7a07d69 100644 --- a/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/ShaderFactoryInterface.kt +++ b/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/ShaderFactoryInterface.kt @@ -50,6 +50,8 @@ abstract class ShaderFactoryInterface { abstract fun createSphereEffectShader(): SphereEffectShaderInterface + abstract fun createSkySphereShader(): SkySphereShaderInterface + public class CppProxy : ShaderFactoryInterface { private val nativeRef: Long private val destroyed: AtomicBoolean = AtomicBoolean(false) @@ -190,5 +192,11 @@ abstract class ShaderFactoryInterface { return native_createSphereEffectShader(this.nativeRef) } private external fun native_createSphereEffectShader(_nativeRef: Long): SphereEffectShaderInterface + + override fun createSkySphereShader(): SkySphereShaderInterface { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + return native_createSkySphereShader(this.nativeRef) + } + private external fun native_createSkySphereShader(_nativeRef: Long): SkySphereShaderInterface } } diff --git a/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface.kt b/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface.kt new file mode 100644 index 000000000..a5dd37e3c --- /dev/null +++ b/bridging/android/java/io/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface.kt @@ -0,0 +1,42 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +package io.openmobilemaps.mapscore.shared.graphics.shader + +import com.snapchat.djinni.NativeObjectManager +import java.util.concurrent.atomic.AtomicBoolean + +abstract class SkySphereShaderInterface { + + abstract fun asShaderProgramInterface(): ShaderProgramInterface + + abstract fun setCameraProperties(inverseVP: ArrayList, cameraPosition: io.openmobilemaps.mapscore.shared.graphics.common.Vec3D) + + public class CppProxy : SkySphereShaderInterface { + private val nativeRef: Long + private val destroyed: AtomicBoolean = AtomicBoolean(false) + + private constructor(nativeRef: Long) { + if (nativeRef == 0L) error("nativeRef is zero") + this.nativeRef = nativeRef + NativeObjectManager.register(this, nativeRef) + } + + companion object { + @JvmStatic + external fun nativeDestroy(nativeRef: Long) + } + + override fun asShaderProgramInterface(): ShaderProgramInterface { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + return native_asShaderProgramInterface(this.nativeRef) + } + private external fun native_asShaderProgramInterface(_nativeRef: Long): ShaderProgramInterface + + override fun setCameraProperties(inverseVP: ArrayList, cameraPosition: io.openmobilemaps.mapscore.shared.graphics.common.Vec3D) { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + native_setCameraProperties(this.nativeRef, inverseVP, cameraPosition) + } + private external fun native_setCameraProperties(_nativeRef: Long, inverseVP: ArrayList, cameraPosition: io.openmobilemaps.mapscore.shared.graphics.common.Vec3D) + } +} diff --git a/bridging/android/java/io/openmobilemaps/mapscore/shared/map/MapCameraInterface.kt b/bridging/android/java/io/openmobilemaps/mapscore/shared/map/MapCameraInterface.kt index eb2955453..cb360d45a 100644 --- a/bridging/android/java/io/openmobilemaps/mapscore/shared/map/MapCameraInterface.kt +++ b/bridging/android/java/io/openmobilemaps/mapscore/shared/map/MapCameraInterface.kt @@ -97,12 +97,16 @@ abstract class MapCameraInterface { abstract fun getLastVpMatrix(): ArrayList? + abstract fun getLastInverseVpMatrix(): ArrayList? + abstract fun getLastVpMatrixViewBounds(): io.openmobilemaps.mapscore.shared.map.coordinates.RectCoord? abstract fun getLastVpMatrixRotation(): Float? abstract fun getLastVpMatrixZoom(): Float? + abstract fun getLastCameraPosition(): io.openmobilemaps.mapscore.shared.graphics.common.Vec3D? + abstract fun asMapCamera3d(): MapCamera3dInterface? public class CppProxy : MapCameraInterface { @@ -366,6 +370,12 @@ abstract class MapCameraInterface { } private external fun native_getLastVpMatrix(_nativeRef: Long): ArrayList? + override fun getLastInverseVpMatrix(): ArrayList? { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + return native_getLastInverseVpMatrix(this.nativeRef) + } + private external fun native_getLastInverseVpMatrix(_nativeRef: Long): ArrayList? + override fun getLastVpMatrixViewBounds(): io.openmobilemaps.mapscore.shared.map.coordinates.RectCoord? { assert(!this.destroyed.get()) { error("trying to use a destroyed object") } return native_getLastVpMatrixViewBounds(this.nativeRef) @@ -384,6 +394,12 @@ abstract class MapCameraInterface { } private external fun native_getLastVpMatrixZoom(_nativeRef: Long): Float? + override fun getLastCameraPosition(): io.openmobilemaps.mapscore.shared.graphics.common.Vec3D? { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + return native_getLastCameraPosition(this.nativeRef) + } + private external fun native_getLastCameraPosition(_nativeRef: Long): io.openmobilemaps.mapscore.shared.graphics.common.Vec3D? + override fun asMapCamera3d(): MapCamera3dInterface? { assert(!this.destroyed.get()) { error("trying to use a destroyed object") } return native_asMapCamera3d(this.nativeRef) diff --git a/bridging/android/java/io/openmobilemaps/mapscore/shared/map/layers/skysphere/SkySphereLayerInterface.kt b/bridging/android/java/io/openmobilemaps/mapscore/shared/map/layers/skysphere/SkySphereLayerInterface.kt new file mode 100644 index 000000000..bb0c01413 --- /dev/null +++ b/bridging/android/java/io/openmobilemaps/mapscore/shared/map/layers/skysphere/SkySphereLayerInterface.kt @@ -0,0 +1,48 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +package io.openmobilemaps.mapscore.shared.map.layers.skysphere + +import com.snapchat.djinni.NativeObjectManager +import java.util.concurrent.atomic.AtomicBoolean + +abstract class SkySphereLayerInterface { + + companion object { + @JvmStatic + external fun create(): SkySphereLayerInterface + } + + abstract fun asLayerInterface(): io.openmobilemaps.mapscore.shared.map.LayerInterface + + /** Expects a texture with x: right ascension (longitude), y: declination (latitude) */ + abstract fun setTexture(texture: io.openmobilemaps.mapscore.shared.graphics.objects.TextureHolderInterface) + + public class CppProxy : SkySphereLayerInterface { + private val nativeRef: Long + private val destroyed: AtomicBoolean = AtomicBoolean(false) + + private constructor(nativeRef: Long) { + if (nativeRef == 0L) error("nativeRef is zero") + this.nativeRef = nativeRef + NativeObjectManager.register(this, nativeRef) + } + + companion object { + @JvmStatic + external fun nativeDestroy(nativeRef: Long) + } + + override fun asLayerInterface(): io.openmobilemaps.mapscore.shared.map.LayerInterface { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + return native_asLayerInterface(this.nativeRef) + } + private external fun native_asLayerInterface(_nativeRef: Long): io.openmobilemaps.mapscore.shared.map.LayerInterface + + override fun setTexture(texture: io.openmobilemaps.mapscore.shared.graphics.objects.TextureHolderInterface) { + assert(!this.destroyed.get()) { error("trying to use a destroyed object") } + native_setTexture(this.nativeRef, texture) + } + private external fun native_setTexture(_nativeRef: Long, texture: io.openmobilemaps.mapscore.shared.graphics.objects.TextureHolderInterface) + } +} diff --git a/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.cpp b/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.cpp index 2e6178c82..a89bab0b8 100644 --- a/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.cpp +++ b/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.cpp @@ -11,6 +11,7 @@ #include "NativePolygonGroupShaderInterface.h" #include "NativePolygonPatternGroupShaderInterface.h" #include "NativeRasterShaderInterface.h" +#include "NativeSkySphereShaderInterface.h" #include "NativeSphereEffectShaderInterface.h" #include "NativeStretchInstancedShaderInterface.h" #include "NativeStretchShaderInterface.h" @@ -200,6 +201,14 @@ NativeShaderFactoryInterface::JavaProxy::~JavaProxy() = default; ::djinni::jniExceptionCheck(jniEnv); return ::djinni_generated::NativeSphereEffectShaderInterface::toCpp(jniEnv, jret); } +/*not-null*/ std::shared_ptr<::SkySphereShaderInterface> NativeShaderFactoryInterface::JavaProxy::createSkySphereShader() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeShaderFactoryInterface>::get(); + auto jret = jniEnv->CallObjectMethod(Handle::get().get(), data.method_createSkySphereShader); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni_generated::NativeSkySphereShaderInterface::toCpp(jniEnv, jret); +} CJNIEXPORT void JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shader_ShaderFactoryInterface_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) { @@ -399,4 +408,13 @@ CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shade } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) } +CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shader_ShaderFactoryInterface_00024CppProxy_native_1createSkySphereShader(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::ShaderFactoryInterface>(nativeRef); + auto r = ref->createSkySphereShader(); + return ::djinni::release(::djinni_generated::NativeSkySphereShaderInterface::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + } // namespace djinni_generated diff --git a/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.h b/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.h index 253117f09..29c80805b 100644 --- a/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.h +++ b/bridging/android/jni/graphics/shader/NativeShaderFactoryInterface.h @@ -54,6 +54,7 @@ class NativeShaderFactoryInterface final : ::djinni::JniInterface<::ShaderFactor /*not-null*/ std::shared_ptr<::StretchInstancedShaderInterface> createStretchInstancedShader(bool unitSphere) override; /*not-null*/ std::shared_ptr<::ColorShaderInterface> createIcosahedronColorShader() override; /*not-null*/ std::shared_ptr<::SphereEffectShaderInterface> createSphereEffectShader() override; + /*not-null*/ std::shared_ptr<::SkySphereShaderInterface> createSkySphereShader() override; private: friend ::djinni::JniInterface<::ShaderFactoryInterface, ::djinni_generated::NativeShaderFactoryInterface>; @@ -81,6 +82,7 @@ class NativeShaderFactoryInterface final : ::djinni::JniInterface<::ShaderFactor const jmethodID method_createStretchInstancedShader { ::djinni::jniGetMethodID(clazz.get(), "createStretchInstancedShader", "(Z)Lio/openmobilemaps/mapscore/shared/graphics/shader/StretchInstancedShaderInterface;") }; const jmethodID method_createIcosahedronColorShader { ::djinni::jniGetMethodID(clazz.get(), "createIcosahedronColorShader", "()Lio/openmobilemaps/mapscore/shared/graphics/shader/ColorShaderInterface;") }; const jmethodID method_createSphereEffectShader { ::djinni::jniGetMethodID(clazz.get(), "createSphereEffectShader", "()Lio/openmobilemaps/mapscore/shared/graphics/shader/SphereEffectShaderInterface;") }; + const jmethodID method_createSkySphereShader { ::djinni::jniGetMethodID(clazz.get(), "createSkySphereShader", "()Lio/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface;") }; }; } // namespace djinni_generated diff --git a/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.cpp b/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.cpp new file mode 100644 index 000000000..6401ddd2f --- /dev/null +++ b/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.cpp @@ -0,0 +1,41 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +#include "NativeSkySphereShaderInterface.h" // my header +#include "Marshal.hpp" +#include "NativeShaderProgramInterface.h" +#include "NativeVec3D.h" + +namespace djinni_generated { + +NativeSkySphereShaderInterface::NativeSkySphereShaderInterface() : ::djinni::JniInterface<::SkySphereShaderInterface, NativeSkySphereShaderInterface>("io/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface$CppProxy") {} + +NativeSkySphereShaderInterface::~NativeSkySphereShaderInterface() = default; + + +CJNIEXPORT void JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shader_SkySphereShaderInterface_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + delete reinterpret_cast<::djinni::CppProxyHandle<::SkySphereShaderInterface>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shader_SkySphereShaderInterface_00024CppProxy_native_1asShaderProgramInterface(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::SkySphereShaderInterface>(nativeRef); + auto r = ref->asShaderProgramInterface(); + return ::djinni::release(::djinni_generated::NativeShaderProgramInterface::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_io_openmobilemaps_mapscore_shared_graphics_shader_SkySphereShaderInterface_00024CppProxy_native_1setCameraProperties(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_inverseVP, ::djinni_generated::NativeVec3D::JniType j_cameraPosition) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::SkySphereShaderInterface>(nativeRef); + ref->setCameraProperties(::djinni::List<::djinni::F32>::toCpp(jniEnv, j_inverseVP), + ::djinni_generated::NativeVec3D::toCpp(jniEnv, j_cameraPosition)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +} // namespace djinni_generated diff --git a/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.h b/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.h new file mode 100644 index 000000000..7db33412f --- /dev/null +++ b/bridging/android/jni/graphics/shader/NativeSkySphereShaderInterface.h @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +#pragma once + +#include "SkySphereShaderInterface.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeSkySphereShaderInterface final : ::djinni::JniInterface<::SkySphereShaderInterface, NativeSkySphereShaderInterface> { +public: + using CppType = std::shared_ptr<::SkySphereShaderInterface>; + using CppOptType = std::shared_ptr<::SkySphereShaderInterface>; + using JniType = jobject; + + using Boxed = NativeSkySphereShaderInterface; + + ~NativeSkySphereShaderInterface(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeSkySphereShaderInterface(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::SkySphereShaderInterface, NativeSkySphereShaderInterface>; + +}; + +} // namespace djinni_generated diff --git a/bridging/android/jni/map/NativeMapCameraInterface.cpp b/bridging/android/jni/map/NativeMapCameraInterface.cpp index 1549209ee..235712f1a 100644 --- a/bridging/android/jni/map/NativeMapCameraInterface.cpp +++ b/bridging/android/jni/map/NativeMapCameraInterface.cpp @@ -10,6 +10,7 @@ #include "NativeMapInterface.h" #include "NativeRectCoord.h" #include "NativeVec2F.h" +#include "NativeVec3D.h" namespace djinni_generated { @@ -398,6 +399,15 @@ CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraI } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) } +CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraInterface_00024CppProxy_native_1getLastInverseVpMatrix(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::MapCameraInterface>(nativeRef); + auto r = ref->getLastInverseVpMatrix(); + return ::djinni::release(::djinni::Optional>::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + CJNIEXPORT ::djinni_generated::NativeRectCoord::Boxed::JniType JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraInterface_00024CppProxy_native_1getLastVpMatrixViewBounds(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) { try { @@ -425,6 +435,15 @@ CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraI } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) } +CJNIEXPORT ::djinni_generated::NativeVec3D::Boxed::JniType JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraInterface_00024CppProxy_native_1getLastCameraPosition(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::MapCameraInterface>(nativeRef); + auto r = ref->getLastCameraPosition(); + return ::djinni::release(::djinni::Optional::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_map_MapCameraInterface_00024CppProxy_native_1asMapCamera3d(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) { try { diff --git a/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.cpp b/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.cpp new file mode 100644 index 000000000..9abd71d04 --- /dev/null +++ b/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.cpp @@ -0,0 +1,47 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +#include "NativeSkySphereLayerInterface.h" // my header +#include "NativeLayerInterface.h" +#include "NativeTextureHolderInterface.h" + +namespace djinni_generated { + +NativeSkySphereLayerInterface::NativeSkySphereLayerInterface() : ::djinni::JniInterface<::SkySphereLayerInterface, NativeSkySphereLayerInterface>("io/openmobilemaps/mapscore/shared/map/layers/skysphere/SkySphereLayerInterface$CppProxy") {} + +NativeSkySphereLayerInterface::~NativeSkySphereLayerInterface() = default; + + +CJNIEXPORT void JNICALL Java_io_openmobilemaps_mapscore_shared_map_layers_skysphere_SkySphereLayerInterface_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + delete reinterpret_cast<::djinni::CppProxyHandle<::SkySphereLayerInterface>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_io_openmobilemaps_mapscore_shared_map_layers_skysphere_SkySphereLayerInterface_create(JNIEnv* jniEnv, jobject /*this*/) +{ + try { + auto r = ::SkySphereLayerInterface::create(); + return ::djinni::release(::djinni_generated::NativeSkySphereLayerInterface::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT ::djinni_generated::NativeLayerInterface::JniType JNICALL Java_io_openmobilemaps_mapscore_shared_map_layers_skysphere_SkySphereLayerInterface_00024CppProxy_native_1asLayerInterface(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::SkySphereLayerInterface>(nativeRef); + auto r = ref->asLayerInterface(); + return ::djinni::release(::djinni_generated::NativeLayerInterface::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_io_openmobilemaps_mapscore_shared_map_layers_skysphere_SkySphereLayerInterface_00024CppProxy_native_1setTexture(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, ::djinni_generated::NativeTextureHolderInterface::JniType j_texture) +{ + try { + const auto& ref = ::djinni::objectFromHandleAddress<::SkySphereLayerInterface>(nativeRef); + ref->setTexture(::djinni_generated::NativeTextureHolderInterface::toCpp(jniEnv, j_texture)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +} // namespace djinni_generated diff --git a/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.h b/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.h new file mode 100644 index 000000000..0bc327269 --- /dev/null +++ b/bridging/android/jni/map/layers/skysphere/NativeSkySphereLayerInterface.h @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +#pragma once + +#include "SkySphereLayerInterface.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeSkySphereLayerInterface final : ::djinni::JniInterface<::SkySphereLayerInterface, NativeSkySphereLayerInterface> { +public: + using CppType = std::shared_ptr<::SkySphereLayerInterface>; + using CppOptType = std::shared_ptr<::SkySphereLayerInterface>; + using JniType = jobject; + + using Boxed = NativeSkySphereLayerInterface; + + ~NativeSkySphereLayerInterface(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeSkySphereLayerInterface(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::SkySphereLayerInterface, NativeSkySphereLayerInterface>; + +}; + +} // namespace djinni_generated diff --git a/bridging/ios/MCMapCameraInterface+Private.mm b/bridging/ios/MCMapCameraInterface+Private.mm index d95492d8e..3bed92afd 100644 --- a/bridging/ios/MCMapCameraInterface+Private.mm +++ b/bridging/ios/MCMapCameraInterface+Private.mm @@ -13,6 +13,7 @@ #import "MCMapInterface+Private.h" #import "MCRectCoord+Private.h" #import "MCVec2F+Private.h" +#import "MCVec3D+Private.h" #include #include #include @@ -343,6 +344,13 @@ - (void)setBoundsRestrictWholeVisibleRect:(BOOL)enabled { } DJINNI_TRANSLATE_EXCEPTIONS() } +- (nullable NSArray *)getLastInverseVpMatrix { + try { + auto objcpp_result_ = _cppRefHandle.get()->getLastInverseVpMatrix(); + return ::djinni::Optional>::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + - (nullable MCRectCoord *)getLastVpMatrixViewBounds { try { auto objcpp_result_ = _cppRefHandle.get()->getLastVpMatrixViewBounds(); @@ -364,6 +372,13 @@ - (nullable NSNumber *)getLastVpMatrixZoom { } DJINNI_TRANSLATE_EXCEPTIONS() } +- (nullable MCVec3D *)getLastCameraPosition { + try { + auto objcpp_result_ = _cppRefHandle.get()->getLastCameraPosition(); + return ::djinni::Optional::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + - (nullable MCMapCamera3dInterface *)asMapCamera3d { try { auto objcpp_result_ = _cppRefHandle.get()->asMapCamera3d(); diff --git a/bridging/ios/MCMapCameraInterface.h b/bridging/ios/MCMapCameraInterface.h index 04ac91fd6..586e85499 100644 --- a/bridging/ios/MCMapCameraInterface.h +++ b/bridging/ios/MCMapCameraInterface.h @@ -6,6 +6,7 @@ #import "MCMapCameraListenerInterface.h" #import "MCRectCoord.h" #import "MCVec2F.h" +#import "MCVec3D.h" #import @class MCMapCamera3dInterface; @class MCMapCameraInterface; @@ -116,12 +117,16 @@ - (nullable NSArray *)getLastVpMatrix; +- (nullable NSArray *)getLastInverseVpMatrix; + - (nullable MCRectCoord *)getLastVpMatrixViewBounds; - (nullable NSNumber *)getLastVpMatrixRotation; - (nullable NSNumber *)getLastVpMatrixZoom; +- (nullable MCVec3D *)getLastCameraPosition; + - (nullable MCMapCamera3dInterface *)asMapCamera3d; @end diff --git a/bridging/ios/MCShaderFactoryInterface+Private.mm b/bridging/ios/MCShaderFactoryInterface+Private.mm index 300c45af7..5a23c94c1 100644 --- a/bridging/ios/MCShaderFactoryInterface+Private.mm +++ b/bridging/ios/MCShaderFactoryInterface+Private.mm @@ -15,6 +15,7 @@ #import "MCPolygonGroupShaderInterface+Private.h" #import "MCPolygonPatternGroupShaderInterface+Private.h" #import "MCRasterShaderInterface+Private.h" +#import "MCSkySphereShaderInterface+Private.h" #import "MCSphereEffectShaderInterface+Private.h" #import "MCStretchInstancedShaderInterface+Private.h" #import "MCStretchShaderInterface+Private.h" @@ -195,6 +196,13 @@ - (id)initWithCpp:(const std::shared_ptr<::ShaderFactoryInterface>&)cppRef } DJINNI_TRANSLATE_EXCEPTIONS() } +- (nullable id)createSkySphereShader { + try { + auto objcpp_result_ = _cppRefHandle.get()->createSkySphereShader(); + return ::djinni_generated::SkySphereShaderInterface::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + namespace djinni_generated { class ShaderFactoryInterface::ObjcProxy final @@ -353,6 +361,13 @@ - (id)initWithCpp:(const std::shared_ptr<::ShaderFactoryInterface>&)cppRef return ::djinni_generated::SphereEffectShaderInterface::toCpp(objcpp_result_); } } + /*not-null*/ std::shared_ptr<::SkySphereShaderInterface> createSkySphereShader() override + { + @autoreleasepool { + auto objcpp_result_ = [djinni_private_get_proxied_objc_object() createSkySphereShader]; + return ::djinni_generated::SkySphereShaderInterface::toCpp(objcpp_result_); + } + } }; } // namespace djinni_generated diff --git a/bridging/ios/MCShaderFactoryInterface.h b/bridging/ios/MCShaderFactoryInterface.h index fe1a985b1..c3df59c9a 100644 --- a/bridging/ios/MCShaderFactoryInterface.h +++ b/bridging/ios/MCShaderFactoryInterface.h @@ -10,6 +10,7 @@ @protocol MCPolygonGroupShaderInterface; @protocol MCPolygonPatternGroupShaderInterface; @protocol MCRasterShaderInterface; +@protocol MCSkySphereShaderInterface; @protocol MCSphereEffectShaderInterface; @protocol MCStretchInstancedShaderInterface; @protocol MCStretchShaderInterface; @@ -63,4 +64,6 @@ - (nullable id)createSphereEffectShader; +- (nullable id)createSkySphereShader; + @end diff --git a/bridging/ios/MCSkySphereLayerInterface+Private.h b/bridging/ios/MCSkySphereLayerInterface+Private.h new file mode 100644 index 000000000..d124f4264 --- /dev/null +++ b/bridging/ios/MCSkySphereLayerInterface+Private.h @@ -0,0 +1,33 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni +#ifdef __cplusplus + +#include "SkySphereLayerInterface.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class MCSkySphereLayerInterface; + +namespace djinni_generated { + +class SkySphereLayerInterface +{ +public: + using CppType = std::shared_ptr<::SkySphereLayerInterface>; + using CppOptType = std::shared_ptr<::SkySphereLayerInterface>; + using ObjcType = MCSkySphereLayerInterface*; + + using Boxed = SkySphereLayerInterface; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + +#endif diff --git a/bridging/ios/MCSkySphereLayerInterface+Private.mm b/bridging/ios/MCSkySphereLayerInterface+Private.mm new file mode 100644 index 000000000..50091da35 --- /dev/null +++ b/bridging/ios/MCSkySphereLayerInterface+Private.mm @@ -0,0 +1,75 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +#import "MCSkySphereLayerInterface+Private.h" +#import "MCSkySphereLayerInterface.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#import "DJIMarshal+Private.h" +#import "MCLayerInterface+Private.h" +#import "MCTextureHolderInterface+Private.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface MCSkySphereLayerInterface () + +- (id)initWithCpp:(const std::shared_ptr<::SkySphereLayerInterface>&)cppRef; + +@end + +@implementation MCSkySphereLayerInterface { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::SkySphereLayerInterface>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + ++ (nullable MCSkySphereLayerInterface *)create { + try { + auto objcpp_result_ = ::SkySphereLayerInterface::create(); + return ::djinni_generated::SkySphereLayerInterface::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nullable id)asLayerInterface { + try { + auto objcpp_result_ = _cppRefHandle.get()->asLayerInterface(); + return ::djinni_generated::LayerInterface::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (void)setTexture:(nullable id)texture { + try { + _cppRefHandle.get()->setTexture(::djinni_generated::TextureHolderInterface::toCpp(texture)); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +namespace djinni_generated { + +auto SkySphereLayerInterface::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return objc->_cppRefHandle.get(); +} + +auto SkySphereLayerInterface::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/bridging/ios/MCSkySphereLayerInterface.h b/bridging/ios/MCSkySphereLayerInterface.h new file mode 100644 index 000000000..92a2200e1 --- /dev/null +++ b/bridging/ios/MCSkySphereLayerInterface.h @@ -0,0 +1,19 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +#import "MCLayerInterface.h" +#import "MCTextureHolderInterface.h" +#import +@class MCSkySphereLayerInterface; + + +@interface MCSkySphereLayerInterface : NSObject + ++ (nullable MCSkySphereLayerInterface *)create; + +- (nullable id)asLayerInterface; + +/** Expects a texture with x: right ascension (longitude), y: declination (latitude) */ +- (void)setTexture:(nullable id)texture; + +@end diff --git a/bridging/ios/MCSkySphereShaderInterface+Private.h b/bridging/ios/MCSkySphereShaderInterface+Private.h new file mode 100644 index 000000000..ce207d169 --- /dev/null +++ b/bridging/ios/MCSkySphereShaderInterface+Private.h @@ -0,0 +1,33 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni +#ifdef __cplusplus + +#include "SkySphereShaderInterface.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@protocol MCSkySphereShaderInterface; + +namespace djinni_generated { + +class SkySphereShaderInterface +{ +public: + using CppType = std::shared_ptr<::SkySphereShaderInterface>; + using CppOptType = std::shared_ptr<::SkySphereShaderInterface>; + using ObjcType = id; + + using Boxed = SkySphereShaderInterface; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + +#endif diff --git a/bridging/ios/MCSkySphereShaderInterface+Private.mm b/bridging/ios/MCSkySphereShaderInterface+Private.mm new file mode 100644 index 000000000..501e4a211 --- /dev/null +++ b/bridging/ios/MCSkySphereShaderInterface+Private.mm @@ -0,0 +1,104 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +#import "MCSkySphereShaderInterface+Private.h" +#import "MCSkySphereShaderInterface.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#import "DJIMarshal+Private.h" +#import "DJIObjcWrapperCache+Private.h" +#import "MCShaderProgramInterface+Private.h" +#import "MCVec3D+Private.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface MCSkySphereShaderInterfaceCppProxy : NSObject + +- (id)initWithCpp:(const std::shared_ptr<::SkySphereShaderInterface>&)cppRef; + +@end + +@implementation MCSkySphereShaderInterfaceCppProxy { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::SkySphereShaderInterface>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + +- (nullable id)asShaderProgramInterface { + try { + auto objcpp_result_ = _cppRefHandle.get()->asShaderProgramInterface(); + return ::djinni_generated::ShaderProgramInterface::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (void)setCameraProperties:(nonnull NSArray *)inverseVP + cameraPosition:(nonnull MCVec3D *)cameraPosition { + try { + _cppRefHandle.get()->setCameraProperties(::djinni::List<::djinni::F32>::toCpp(inverseVP), + ::djinni_generated::Vec3D::toCpp(cameraPosition)); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +namespace djinni_generated { + +class SkySphereShaderInterface::ObjcProxy final +: public ::SkySphereShaderInterface +, private ::djinni::ObjcProxyBase +{ + friend class ::djinni_generated::SkySphereShaderInterface; +public: + using ObjcProxyBase::ObjcProxyBase; + /*not-null*/ std::shared_ptr<::ShaderProgramInterface> asShaderProgramInterface() override + { + @autoreleasepool { + auto objcpp_result_ = [djinni_private_get_proxied_objc_object() asShaderProgramInterface]; + return ::djinni_generated::ShaderProgramInterface::toCpp(objcpp_result_); + } + } + void setCameraProperties(const std::vector & c_inverseVP, const ::Vec3D & c_cameraPosition) override + { + @autoreleasepool { + [djinni_private_get_proxied_objc_object() setCameraProperties:(::djinni::List<::djinni::F32>::fromCpp(c_inverseVP)) + cameraPosition:(::djinni_generated::Vec3D::fromCpp(c_cameraPosition))]; + } + } +}; + +} // namespace djinni_generated + +namespace djinni_generated { + +auto SkySphereShaderInterface::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + if ([(id)objc isKindOfClass:[MCSkySphereShaderInterfaceCppProxy class]]) { + return ((MCSkySphereShaderInterfaceCppProxy*)objc)->_cppRefHandle.get(); + } + return ::djinni::get_objc_proxy(objc); +} + +auto SkySphereShaderInterface::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + if (auto cppPtr = dynamic_cast(cpp.get())) { + return cppPtr->djinni_private_get_proxied_objc_object(); + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/bridging/ios/MCSkySphereShaderInterface.h b/bridging/ios/MCSkySphereShaderInterface.h new file mode 100644 index 000000000..caf83a626 --- /dev/null +++ b/bridging/ios/MCSkySphereShaderInterface.h @@ -0,0 +1,16 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +#import "MCVec3D.h" +#import +@protocol MCShaderProgramInterface; + + +@protocol MCSkySphereShaderInterface + +- (nullable id)asShaderProgramInterface; + +- (void)setCameraProperties:(nonnull NSArray *)inverseVP + cameraPosition:(nonnull MCVec3D *)cameraPosition; + +@end diff --git a/djinni/graphics/shader/shader.djinni b/djinni/graphics/shader/shader.djinni index 2cd206e79..061d5d501 100644 --- a/djinni/graphics/shader/shader.djinni +++ b/djinni/graphics/shader/shader.djinni @@ -52,6 +52,8 @@ shader_factory_interface = interface +c +j +o { create_icosahedron_color_shader(): color_shader_interface; create_sphere_effect_shader(): sphere_effect_shader_interface; + + create_sky_sphere_shader(): sky_sphere_shader_interface; } raster_shader_style = record { @@ -93,6 +95,11 @@ sphere_effect_shader_interface = interface +c +o { set_ellipse(coefficients: shared_bytes); } +sky_sphere_shader_interface = interface +c +o { + as_shader_program_interface() : shader_program_interface; + set_camera_properties(inverse_v_p: list, camera_position: vec_3_d); +} + stretch_shader_info = record { scaleX: f32; diff --git a/djinni/map/core.djinni b/djinni/map/core.djinni index 94c9f0751..b04048b04 100644 --- a/djinni/map/core.djinni +++ b/djinni/map/core.djinni @@ -1,3 +1,4 @@ +@extern "../yaml/vec_3_d.yaml" @extern "../yaml/vec_2_f.yaml" @extern "../yaml/vec_2_i.yaml" @extern "../yaml/rect_i.yaml" @@ -195,9 +196,11 @@ map_camera_interface = interface +c { get_last_vp_matrix_d() : optional>; get_last_vp_matrix() : optional>; + get_last_inverse_vp_matrix() : optional>; get_last_vp_matrix_view_bounds() : optional; get_last_vp_matrix_rotation() : optional; get_last_vp_matrix_zoom() : optional; + get_last_camera_position() : optional; as_map_camera_3d(): optional; } diff --git a/djinni/map/layers/skysphere/sky_sphere.djinni b/djinni/map/layers/skysphere/sky_sphere.djinni new file mode 100644 index 000000000..1b329dc54 --- /dev/null +++ b/djinni/map/layers/skysphere/sky_sphere.djinni @@ -0,0 +1,10 @@ +@extern "../../../yaml/layer_interface.yaml" +@extern "../../../yaml/texture_holder_interface.yaml" + +sky_sphere_layer_interface = interface +c { + static create(): sky_sphere_layer_interface; + as_layer_interface(): layer_interface; + + # Expects a texture with x: right ascension (longitude), y: declination (latitude) + set_texture(texture: texture_holder_interface); +} \ No newline at end of file diff --git a/djinni/yaml/sky_sphere_layer_interface.yaml b/djinni/yaml/sky_sphere_layer_interface.yaml new file mode 100644 index 000000000..4ec12cf34 --- /dev/null +++ b/djinni/yaml/sky_sphere_layer_interface.yaml @@ -0,0 +1,39 @@ +# AUTOGENERATED FILE - DO NOT MODIFY! +# This file was generated by Djinni from sky_sphere.djinni +name: sky_sphere_layer_interface +typedef: 'interface +c' +params: [] +prefix: "" +cpp: + typename: '::SkySphereLayerInterface' + header: '"SkySphereLayerInterface.h"' + byValue: false +objc: + typename: 'MCSkySphereLayerInterface' + pointer: true + hash: '%s.hash' + boxed: 'MCSkySphereLayerInterface' + header: '"MCSkySphereLayerInterface.h"' +objcpp: + translator: '::djinni_generated::SkySphereLayerInterface' + header: '"MCSkySphereLayerInterface+Private.h"' +java: + reference: true + typename: 'io.openmobilemaps.mapscore.shared.map.layers.skysphere.SkySphereLayerInterface' + writeToParcel: '%s.writeToParcel(out, flags)' + generic: true + readFromParcel: 'new %s(in)' + hash: '%s.hashCode()' + boxed: 'io.openmobilemaps.mapscore.shared.map.layers.skysphere.SkySphereLayerInterface' +jni: + translator: '::djinni_generated::NativeSkySphereLayerInterface' + header: '"NativeSkySphereLayerInterface.h"' + typename: jobject + typeSignature: 'Lio/openmobilemaps/mapscore/shared/map/layers/skysphere/SkySphereLayerInterface;' +wasm: + translator: '::djinni_generated::NativeSkySphereLayerInterface' + header: '"NativeSkySphereLayerInterface.h"' + typename: em::val +ts: + typename: SkySphereLayerInterface + module: './module' diff --git a/djinni/yaml/sky_sphere_shader_interface.yaml b/djinni/yaml/sky_sphere_shader_interface.yaml new file mode 100644 index 000000000..fbe955262 --- /dev/null +++ b/djinni/yaml/sky_sphere_shader_interface.yaml @@ -0,0 +1,39 @@ +# AUTOGENERATED FILE - DO NOT MODIFY! +# This file was generated by Djinni from shader.djinni +name: sky_sphere_shader_interface +typedef: 'interface +c +o' +params: [] +prefix: "" +cpp: + typename: '::SkySphereShaderInterface' + header: '"SkySphereShaderInterface.h"' + byValue: false +objc: + typename: 'MCSkySphereShaderInterface' + pointer: true + hash: '%s.hash' + boxed: 'MCSkySphereShaderInterface' + header: '"MCSkySphereShaderInterface.h"' +objcpp: + translator: '::djinni_generated::SkySphereShaderInterface' + header: '"MCSkySphereShaderInterface+Private.h"' +java: + reference: true + typename: 'io.openmobilemaps.mapscore.shared.graphics.shader.SkySphereShaderInterface' + writeToParcel: '%s.writeToParcel(out, flags)' + generic: true + readFromParcel: 'new %s(in)' + hash: '%s.hashCode()' + boxed: 'io.openmobilemaps.mapscore.shared.graphics.shader.SkySphereShaderInterface' +jni: + translator: '::djinni_generated::NativeSkySphereShaderInterface' + header: '"NativeSkySphereShaderInterface.h"' + typename: jobject + typeSignature: 'Lio/openmobilemaps/mapscore/shared/graphics/shader/SkySphereShaderInterface;' +wasm: + translator: '::djinni_generated::NativeSkySphereShaderInterface' + header: '"NativeSkySphereShaderInterface.h"' + typename: em::val +ts: + typename: SkySphereShaderInterface + module: './module' diff --git a/shared/public/MapCameraInterface.h b/shared/public/MapCameraInterface.h index dc601da59..2a51ca8d9 100644 --- a/shared/public/MapCameraInterface.h +++ b/shared/public/MapCameraInterface.h @@ -8,6 +8,7 @@ #include "MapCameraListenerInterface.h" #include "RectCoord.h" #include "Vec2F.h" +#include "Vec3D.h" #include #include #include @@ -105,11 +106,15 @@ class MapCameraInterface { virtual std::optional> getLastVpMatrix() = 0; + virtual std::optional> getLastInverseVpMatrix() = 0; + virtual std::optional<::RectCoord> getLastVpMatrixViewBounds() = 0; virtual std::optional getLastVpMatrixRotation() = 0; virtual std::optional getLastVpMatrixZoom() = 0; + virtual std::optional<::Vec3D> getLastCameraPosition() = 0; + virtual /*nullable*/ std::shared_ptr asMapCamera3d() = 0; }; diff --git a/shared/public/ShaderFactoryInterface.h b/shared/public/ShaderFactoryInterface.h index e386ce771..63510280a 100644 --- a/shared/public/ShaderFactoryInterface.h +++ b/shared/public/ShaderFactoryInterface.h @@ -13,6 +13,7 @@ class LineGroupShaderInterface; class PolygonGroupShaderInterface; class PolygonPatternGroupShaderInterface; class RasterShaderInterface; +class SkySphereShaderInterface; class SphereEffectShaderInterface; class StretchInstancedShaderInterface; class StretchShaderInterface; @@ -64,4 +65,6 @@ class ShaderFactoryInterface { virtual /*not-null*/ std::shared_ptr createIcosahedronColorShader() = 0; virtual /*not-null*/ std::shared_ptr createSphereEffectShader() = 0; + + virtual /*not-null*/ std::shared_ptr createSkySphereShader() = 0; }; diff --git a/shared/public/SkySphereLayerInterface.h b/shared/public/SkySphereLayerInterface.h new file mode 100644 index 000000000..c26de51f2 --- /dev/null +++ b/shared/public/SkySphereLayerInterface.h @@ -0,0 +1,20 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from sky_sphere.djinni + +#pragma once + +#include "LayerInterface.h" +#include "TextureHolderInterface.h" +#include + +class SkySphereLayerInterface { +public: + virtual ~SkySphereLayerInterface() = default; + + static /*not-null*/ std::shared_ptr create(); + + virtual /*not-null*/ std::shared_ptr<::LayerInterface> asLayerInterface() = 0; + + /** Expects a texture with x: right ascension (longitude), y: declination (latitude) */ + virtual void setTexture(const /*not-null*/ std::shared_ptr<::TextureHolderInterface> & texture) = 0; +}; diff --git a/shared/public/SkySphereShaderInterface.h b/shared/public/SkySphereShaderInterface.h new file mode 100644 index 000000000..8827a3243 --- /dev/null +++ b/shared/public/SkySphereShaderInterface.h @@ -0,0 +1,19 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from shader.djinni + +#pragma once + +#include "Vec3D.h" +#include +#include + +class ShaderProgramInterface; + +class SkySphereShaderInterface { +public: + virtual ~SkySphereShaderInterface() = default; + + virtual /*not-null*/ std::shared_ptr asShaderProgramInterface() = 0; + + virtual void setCameraProperties(const std::vector & inverseVP, const ::Vec3D & cameraPosition) = 0; +}; diff --git a/shared/src/map/camera/MapCamera2d.cpp b/shared/src/map/camera/MapCamera2d.cpp index 33deb1684..ea6665488 100644 --- a/shared/src/map/camera/MapCamera2d.cpp +++ b/shared/src/map/camera/MapCamera2d.cpp @@ -419,6 +419,7 @@ std::vector MapCamera2d::getVpMatrix() { Coord renderCoordCenter = conversionHelper->convertToRenderSystem(centerPosition); + std::lock_guard lock(vpDataMutex); Matrix::setIdentityM(newVpMatrix, 0); @@ -431,11 +432,11 @@ std::vector MapCamera2d::getVpMatrix() { Matrix::rotateM(newVpMatrix, 0.0, currentRotation, 0.0, 0.0, 1.0); - std::lock_guard lock(vpDataMutex); - origin.x = renderCoordCenter.x; origin.y = renderCoordCenter.y; + Matrix::invertM(newInverseVpMatrix, 0, newVpMatrix, 0); + lastVpBounds = viewBounds; lastVpRotation = currentRotation; lastVpZoom = currentZoom; @@ -458,6 +459,15 @@ std::optional> MapCamera2d::getLastVpMatrix() { return vpCopy; } +std::optional> MapCamera2d::getLastInverseVpMatrix() { + if (!lastVpBounds) { + return std::nullopt; + } + std::vector inverseVpCopy; + std::copy(newInverseVpMatrix.begin(), newInverseVpMatrix.end(), std::back_inserter(inverseVpCopy)); + return inverseVpCopy; +} + Vec3D MapCamera2d::getOrigin() { return origin; } @@ -477,6 +487,10 @@ std::optional MapCamera2d::getLastVpMatrixZoom() { return lastVpZoom; } +std::optional<::Vec3D> MapCamera2d::getLastCameraPosition() { + return Vec3D(0.0, 0.0, 0.0); +} + /** this method is called just before the update methods on all layers */ void MapCamera2d::update() { inertiaStep(); diff --git a/shared/src/map/camera/MapCamera2d.h b/shared/src/map/camera/MapCamera2d.h index 000c60271..563c39977 100644 --- a/shared/src/map/camera/MapCamera2d.h +++ b/shared/src/map/camera/MapCamera2d.h @@ -89,12 +89,16 @@ class MapCamera2d : public MapCameraInterface, std::optional> getLastVpMatrix() override; + std::optional> getLastInverseVpMatrix() override; + std::optional<::RectCoord> getLastVpMatrixViewBounds() override; std::optional getLastVpMatrixRotation() override; std::optional getLastVpMatrixZoom() override; + std::optional<::Vec3D> getLastCameraPosition() override; + void notifyListenerBoundsChange() override; /** this method is called just before the update methods on all layers */ @@ -242,6 +246,7 @@ class MapCamera2d : public MapCameraInterface, RectCoord getRectFromViewport(const Vec2I &sizeViewport, const Coord ¢er); std::vector newVpMatrix = std::vector(16, 0.0); + std::vector newInverseVpMatrix = std::vector(16, 0.0); Vec3D origin = Vec3D(0, 0, 0); }; diff --git a/shared/src/map/camera/MapCamera3d.cpp b/shared/src/map/camera/MapCamera3d.cpp index 2438c91c7..305393655 100644 --- a/shared/src/map/camera/MapCamera3d.cpp +++ b/shared/src/map/camera/MapCamera3d.cpp @@ -500,6 +500,13 @@ std::optional, std::vector, Vec3D>> MapCa std::vector newProjectionMatrixF = VectorHelper::convertToFloat(newProjectionMatrix); std::vector newViewMatrixF = VectorHelper::convertToFloat(newViewMatrix); + std::vector newInverseViewMatrix(16, 0.0); + gluInvertMatrix(newViewMatrix, newInverseViewMatrix); + Vec4D cameraOriginVector = MatrixD::multiply(newInverseViewMatrix, Vec4D(0.0, 0.0, 0.0, 1.0)); + Vec3D newCameraPosition = Vec3D(cameraOriginVector.x / cameraOriginVector.w, + cameraOriginVector.y / cameraOriginVector.w, + cameraOriginVector.z / cameraOriginVector.w); + if (onlyReturnResult) { return std::tuple{newVpMatrix, newInverseMatrix, newOrigin}; } else { @@ -516,6 +523,7 @@ std::optional, std::vector, Vec3D>> MapCa validVpMatrix = true; origin = newOrigin; lastScalingFactor = mapUnitsFromPixels(1.0); + lastCameraPosition = newCameraPosition; return std::nullopt; } @@ -549,6 +557,17 @@ std::optional> MapCamera3d::getLastVpMatrix() { return vpCopy; } +std::optional> MapCamera3d::getLastInverseVpMatrix() { + // TODO: Add back as soon as visiblerect calculation is done + // if (!lastInverseVpBounds) { + // return std::nullopt; + // } + std::lock_guard lock(matrixMutex); + std::vector inverseVpCopy; + std::copy(inverseVPMatrix.begin(), inverseVPMatrix.end(), std::back_inserter(inverseVpCopy)); + return inverseVpCopy; +} + std::optional<::RectCoord> MapCamera3d::getLastVpMatrixViewBounds() { std::lock_guard lock(matrixMutex); return lastVpBounds; @@ -564,6 +583,11 @@ std::optional MapCamera3d::getLastVpMatrixZoom() { return lastVpZoom; } +std::optional<::Vec3D> MapCamera3d::getLastCameraPosition() { + std::lock_guard lock(matrixMutex); + return lastCameraPosition; +} + /** this method is called just before the update methods on all layers */ void MapCamera3d::update() { inertiaStep(); diff --git a/shared/src/map/camera/MapCamera3d.h b/shared/src/map/camera/MapCamera3d.h index e8c8fc44d..bc8ee39c3 100644 --- a/shared/src/map/camera/MapCamera3d.h +++ b/shared/src/map/camera/MapCamera3d.h @@ -99,12 +99,16 @@ class MapCamera3d : public MapCameraInterface, std::optional> getLastVpMatrix() override; + std::optional> getLastInverseVpMatrix() override; + std::optional<::RectCoord> getLastVpMatrixViewBounds() override; std::optional getLastVpMatrixRotation() override; std::optional getLastVpMatrixZoom() override; + std::optional<::Vec3D> getLastCameraPosition() override; + /** this method is called just before the update methods on all layers */ virtual void update() override; @@ -231,6 +235,7 @@ class MapCamera3d : public MapCameraInterface, std::optional lastVpBounds = std::nullopt; std::optional lastVpRotation = std::nullopt; std::optional lastVpZoom = std::nullopt; + std::optional lastCameraPosition = std::nullopt; bool cameraFrozen = false; @@ -305,6 +310,7 @@ class MapCamera3d : public MapCameraInterface, std::vector inverseVPMatrix = std::vector(16, 0.0); std::vector viewMatrix = std::vector(16, 0.0); std::vector projectionMatrix = std::vector(16, 0.0); + Vec3D cameraPosition = Vec3D(0.0, 0.0, 0.0); Vec3D origin; float verticalFov; float horizontalFov; diff --git a/shared/src/map/layers/skysphere/SkySphereLayer.cpp b/shared/src/map/layers/skysphere/SkySphereLayer.cpp new file mode 100644 index 000000000..02bc76d37 --- /dev/null +++ b/shared/src/map/layers/skysphere/SkySphereLayer.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +#include "SkySphereLayer.h" +#include "MapInterface.h" +#include "GraphicsObjectInterface.h" +#include "RenderPass.h" +#include "RenderObject.h" + +// SimpleLayerInterface + +void SkySphereLayer::update() { + auto mapInterface = this->mapInterface; + auto camera = mapInterface ? mapInterface->getCamera() : nullptr; + if (!camera) { + return; + } + + auto inverseVpMatrix = camera->getLastInverseVpMatrix(); + auto cameraPosition = camera->getLastCameraPosition(); + if (inverseVpMatrix && cameraPosition) { + shader->setCameraProperties(*inverseVpMatrix, *cameraPosition); + } +} + +std::vector> SkySphereLayer::buildRenderPasses() { + return (isHidden || !skySphereTexture) ? std::vector>() : renderPasses; +} + +void SkySphereLayer::onAdded(const std::shared_ptr &mapInterface, int32_t layerIndex) { + this->mapInterface = mapInterface; + + auto scheduler = mapInterface->getScheduler(); + auto selfMailbox = std::make_shared(scheduler); + this->mailbox = selfMailbox; + + shader = mapInterface->getShaderFactory()->createSkySphereShader(); + quad = mapInterface->getGraphicsObjectFactory()->createQuad(shader->asShaderProgramInterface()); + quad->setFrame(Quad3dD(Vec3D(-1, 1, 0), + Vec3D(1, 1, 0), + Vec3D(1, -1, 0), + Vec3D(-1, -1, 0)), + RectD(-1, -1, 2, 2), + Vec3D(0, 0, 0), + false); +} + +void SkySphereLayer::onRemoved() { + this->mapInterface = nullptr; + this->mailbox = nullptr; + + if (quad->asGraphicsObject()->isReady()) { + quad->asGraphicsObject()->clear(); + } + this->quad = nullptr; + this->shader = nullptr; +} + +void SkySphereLayer::pause() { + quad->asGraphicsObject()->clear(); +} + +void SkySphereLayer::resume() { + setupSkySphere(); +} + +void SkySphereLayer::hide() { + isHidden = false; +} + +void SkySphereLayer::show() { + isHidden = true; +} + +// SkySphereLayerInterface + +std::shared_ptr<::LayerInterface> SkySphereLayer::asLayerInterface() { + return shared_from_this(); +} + +void SkySphereLayer::setTexture(const std::shared_ptr<::TextureHolderInterface> &texture) { + this->skySphereTexture = texture; + auto selfMailbox = this->mailbox; + if (selfMailbox) { + WeakActor(selfMailbox, weak_from_this()) + .message(MailboxExecutionEnvironment::graphics, MFN(&SkySphereLayer::setupSkySphere)); + } +} + +void SkySphereLayer::setupSkySphere() { + auto mapInterface = this->mapInterface; + auto renderingContext = mapInterface ? mapInterface->getRenderingContext() : nullptr; + if (!renderingContext) { + return; + } + + auto skySphereTexture = this->skySphereTexture; + auto quad = this->quad; + if (skySphereTexture && renderingContext && quad) { + quad->asGraphicsObject()->setup(renderingContext); + quad->loadTexture(renderingContext, skySphereTexture); + + std::vector> renderObjects = { + std::make_shared(quad->asGraphicsObject(), false) + }; + renderPasses = {std::make_shared(RenderPassConfig(0, false), renderObjects)}; + } +} \ No newline at end of file diff --git a/shared/src/map/layers/skysphere/SkySphereLayer.h b/shared/src/map/layers/skysphere/SkySphereLayer.h new file mode 100644 index 000000000..f653083f7 --- /dev/null +++ b/shared/src/map/layers/skysphere/SkySphereLayer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +#pragma once + +#include "Actor.h" +#include "MapCameraInterface.h" +#include "Quad2dInterface.h" +#include "SimpleLayerInterface.h" +#include "SkySphereLayerInterface.h" +#include "SkySphereShaderInterface.h" + +class SkySphereLayer + : public ActorObject, + public SimpleLayerInterface, + public SkySphereLayerInterface, + public std::enable_shared_from_this { +public: + // SimpleLayerInterface + + void update() override; + + std::vector> buildRenderPasses() override; + + void onAdded(const std::shared_ptr &mapInterface, int32_t layerIndex) override; + + void onRemoved() override; + + void pause() override; + + void resume() override; + + void hide() override; + + void show() override; + + // SkySphereLayerInterface + + std::shared_ptr<::LayerInterface> asLayerInterface() override; + + void setTexture(const std::shared_ptr<::TextureHolderInterface> &texture) override; + +private: + void setupSkySphere(); + + std::shared_ptr mapInterface; + + std::shared_ptr shader; + std::shared_ptr<::Quad2dInterface> quad; + + std::vector> renderPasses; + bool isHidden = false; + + std::shared_ptr<::TextureHolderInterface> skySphereTexture; +}; + diff --git a/shared/src/map/layers/skysphere/SkySphereLayerInterface.cpp b/shared/src/map/layers/skysphere/SkySphereLayerInterface.cpp new file mode 100644 index 000000000..c3e5d4e6e --- /dev/null +++ b/shared/src/map/layers/skysphere/SkySphereLayerInterface.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +#include "SkySphereLayerInterface.h" +#include "SkySphereLayer.h" + +std::shared_ptr SkySphereLayerInterface::create() { + return std::make_shared(); +} \ No newline at end of file