tirbofish/dropbear · commit
9a88505ee88bc8e5b33702f180dccec4c18dbe4a
refactor + wip: changed to a more "abstract" component querying system, allowing for other developers to create their own components. also shuffled the code, and now got the commonMain working (to a documentable stage).
todo:
- implement jvmMain functions, implement JNI rust code and test to see if physics is working
- if physics is working:
- implement nativeLibMain and native rust code
- if physics is NOT working:
- fix up PhysicsState in rust and kotlin and see what the issue is, then resolve.
- fix up magna-carta to support new system
will i hit my deadline (basic physics working by new years)??? hopefully so...
Signature present but could not be verified.Unverified
@@ -32,18 +32,12 @@ val libPathProvider = provider { layout.projectDirectory.file("libs/$libName").asFile ) - val foundFile = candidates.firstOrNull { it.exists() } - if (foundFile != null) { - foundFile.absolutePath - } else { - println("No Rust library exists") - "" - } + candidates.firstOrNull { it.exists() }?.absolutePath ?: "" } kotlin { jvm { - withJava() + } val nativeTarget = when { @@ -81,19 +75,16 @@ kotlin { binaries { sharedLib { baseName = "dropbear" - if (isLinux || isMacOs) { linkerOpts("-L$nativeLibDir", "-l$nativeLibNameForLinking", "-Wl,-rpath,\\\$ORIGIN") } else if (isMingwX64) { - val importLibName = "$nativeLibNameForLinking.dll.lib" - val importLibPath = file("$nativeLibDir/$importLibName").absolutePath - linkerOpts(importLibPath) + linkerOpts(file("$nativeLibDir/$nativeLibNameForLinking.dll.lib").absolutePath) } } } } } else { - println("Skipping native target configuration due to missing library path.") + println("WARNING: Rust library not found. Native compilation will skip linking against eucalyptus_core.") nativeTarget.apply { compilations.getByName("main") { cinterops { @@ -120,8 +111,9 @@ kotlin { jvmMain { kotlin.srcDirs("src/jvmMain/kotlin", "build/magna-carta") - dependencies { + dependencies { + implementation(kotlin("stdlib")) } } } @@ -137,21 +129,41 @@ kotlin { } } -tasks.register<JavaCompile>("generateJniHeaders") { - val outputDir = layout.buildDirectory.dir("generated/jni-headers") - options.headerOutputDirectory.set(outputDir.get().asFile) +val extractJavaSources by tasks.registering(Copy::class) { + group = "jni" + description = "Copies .java files from jvmMain/kotlin to a temp directory for header generation" + + from("src/jvmMain/kotlin") + include("**/*.java") + into(layout.buildDirectory.dir("tmp/java-jni-sources")) +} + +val generateJniHeaders by tasks.registering(JavaCompile::class) { + group = "jni" + description = "Generates JNI headers from extracted Java files" - destinationDirectory.set(layout.buildDirectory.dir("classes/java/jni")) + dependsOn(extractJavaSources, "compileKotlinJvm") + + source(extractJavaSources.map { it.destinationDir }) classpath = files( - tasks.named("compileKotlinJvm"), + tasks.named("compileKotlinJvm").map { it.outputs.files }, + configurations.named("jvmCompileClasspath") ) - source = fileTree("src/jvmMain/java") { - include("**/*.java") + destinationDirectory.set(layout.buildDirectory.dir("tmp/jni-dummy-classes")) + + val headerOutputDir = layout.buildDirectory.dir("generated/jni-headers") + options.headerOutputDirectory.set(headerOutputDir) + + doLast { + println("Generated JNI Headers at: ${headerOutputDir.get().asFile.absolutePath}") } +} - dependsOn("compileKotlinJvm") + +tasks.named("jvmMainClasses") { + dependsOn(generateJniHeaders) } publishing { @@ -165,7 +177,7 @@ publishing { publications.withType<MavenPublication> { pom { name.set("dropbear") - description.set("The dropbear scripting part of the engine... uhh yeah!") + description.set("The dropbear scripting part of the engine") url.set("https://github.com/tirbofish/dropbear") licenses { @@ -179,7 +191,7 @@ publishing { developer { id.set("tirbofish") name.set("tk") - email.set("tirbofish@pm.me") + email.set("4tkbytes@pm.me") } } @@ -198,13 +210,11 @@ tasks.register<Jar>("fatJar") { from(kotlin.jvm().compilations["main"].output) - configurations.named("jvmRuntimeClasspath").get().forEach { file -> - if (file.name.endsWith(".jar")) { - from(zipTree(file)) - } else { - from(file) - } - } + from(configurations.named("jvmRuntimeClasspath").map { + it.map { file -> if (file.isDirectory) file else zipTree(file) } + }) - manifest {} + manifest { + attributes["Implementation-Version"] = project.version + } } @@ -53,6 +53,8 @@ pub fn register_components( component_registry.register_with_default::<Script>(); component_registry.register_with_default::<SerializedMeshRenderer>(); component_registry.register_with_default::<Camera3D>(); + component_registry.register_with_default::<RigidBody>(); + component_registry.register_with_default::<ColliderGroup>(); component_registry.register_converter::<MeshRenderer, SerializedMeshRenderer, _>( |_, _, renderer| { @@ -77,9 +79,6 @@ pub fn register_components( }, ); - component_registry.register_with_default::<RigidBody>(); - component_registry.register_with_default::<ColliderGroup>(); - // // register plugin defined structs // if let Err(e) = plugin_registry.load_plugins() { // fatal!("Failed to load plugins: {}", e); @@ -478,9 +478,9 @@ impl<'a> TabViewer for EditorTabViewer<'a> { log_once::debug_once!("Available components: "); for (id, name) in registry.iter_available_components() { log_once::debug_once!("id: {}, name: {}", id, name); - if name.contains("EntityTransform") { - continue; - } + // if name.contains("EntityTransform") { + // continue; + // } let short_name = name.split("::").last().unwrap_or(name); let display_name = @@ -1,5 +1,5 @@ [versions] -kotlin = "2.1.0" +kotlin = "2.3.0" kotlinxSerialization = "1.8.0" [libraries] @@ -9,11 +9,11 @@ pluginManagement { plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -include("magna-carta-plugin") +//include("magna-carta-plugin") buildCache { local { isEnabled = true } } -include("dropbear-gradle-plugin") +//include("dropbear-gradle-plugin") @@ -1,5 +1,7 @@ package com.dropbear +import com.dropbear.ecs.Component +import com.dropbear.ecs.ComponentType import com.dropbear.math.Vector3D /** @@ -7,44 +9,42 @@ import com.dropbear.math.Vector3D */ class Camera( internal val entity: EntityId, -) { +): Component(entity, "Camera3D") { var eye: Vector3D - get() = native.getCameraEye(this) - set(value) = native.setCameraEye(this, value) + get() = getCameraEye(entity) + set(value) = setCameraEye(entity, value) var target: Vector3D - get() = native.getCameraTarget(this) - set(value) = native.setCameraTarget(this, value) + get() = getCameraTarget(entity) + set(value) = setCameraTarget(entity, value) var up: Vector3D - get() = native.getCameraUp(this) - set(value) = native.setCameraUp(this, value) + get() = getCameraUp(entity) + set(value) = setCameraUp(entity, value) val aspect: Double - get() = native.getCameraAspect(this) + get() = getCameraAspect(entity) var fov_y: Double - get() = native.getCameraFovY(this) - set(value) = native.setCameraFovY(this, value) + get() = getCameraFovY(entity) + set(value) = setCameraFovY(entity, value) var znear: Double - get() = native.getCameraZNear(this) - set(value) = native.setCameraZNear(this, value) + get() = getCameraZNear(entity) + set(value) = setCameraZNear(entity, value) var zfar: Double - get() = native.getCameraZFar(this) - set(value) = native.setCameraZFar(this) + get() = getCameraZFar(entity) + set(value) = setCameraZFar(entity, value) var yaw: Double - get() = native.getCameraYaw(this) - set(value) = native.setCameraYaw(this, value) + get() = getCameraYaw(entity) + set(value) = setCameraYaw(entity, value) var pitch: Double - get() = native.getCameraPitch(this) - set(value) = native.setCameraPitch(this, value) + get() = getCameraPitch(entity) + set(value) = setCameraPitch(entity, value) var speed: Double - get() = native.getCameraSpeed(this) - set(value) = native.setCameraSpeed(this, value) + get() = getCameraSpeed(entity) + set(value) = setCameraSpeed(entity, value) var sensitivity: Double - get() = native.getCameraSensitivity(this) - set(value) = native.setCameraSensitivity(this, value) - - internal lateinit var engine: DropbearEngine + get() = getCameraSensitivity(entity) + set(value) = setCameraSensitivity(entity, value) override fun toString(): String { - return "Camera '${label}' of id $id \n" + + return "Camera component of entity $entity \n" + "eye: $eye\n" + "target: $target\n" + "up: $up\n " + @@ -57,4 +57,34 @@ class Camera( "speed: $speed" + "sensitivity: $sensitivity" } -} + + companion object : ComponentType<Camera> { + override fun get(entityId: EntityId): Camera? { + return if (cameraExistsForEntity(entityId)) Camera(entityId) else null + } + } +} + +expect fun Camera.getCameraEye(entity: EntityId): Vector3D +expect fun Camera.setCameraEye(entity: EntityId, value: Vector3D) +expect fun Camera.getCameraTarget(entity: EntityId): Vector3D +expect fun Camera.setCameraTarget(entity: EntityId, value: Vector3D) +expect fun Camera.getCameraUp(entity: EntityId): Vector3D +expect fun Camera.setCameraUp(entity: EntityId, value: Vector3D) +expect fun Camera.getCameraAspect(entity: EntityId): Double +expect fun Camera.getCameraFovY(entity: EntityId): Double +expect fun Camera.setCameraFovY(entity: EntityId, value: Double) +expect fun Camera.getCameraZNear(entity: EntityId): Double +expect fun Camera.setCameraZNear(entity: EntityId, value: Double) +expect fun Camera.getCameraZFar(entity: EntityId): Double +expect fun Camera.setCameraZFar(entity: EntityId, value: Double) +expect fun Camera.getCameraYaw(entity: EntityId): Double +expect fun Camera.setCameraYaw(entity: EntityId, value: Double) +expect fun Camera.getCameraPitch(entity: EntityId): Double +expect fun Camera.setCameraPitch(entity: EntityId, value: Double) +expect fun Camera.getCameraSpeed(entity: EntityId): Double +expect fun Camera.setCameraSpeed(entity: EntityId, value: Double) +expect fun Camera.getCameraSensitivity(entity: EntityId): Double +expect fun Camera.setCameraSensitivity(entity: EntityId, value: Double) + +expect fun cameraExistsForEntity(entity: EntityId): Boolean @@ -0,0 +1,93 @@ +package com.dropbear + +import com.dropbear.ecs.Component +import com.dropbear.ecs.ComponentType +import com.dropbear.math.Vector3 + +class CustomProperties(val id: EntityId): Component(id, "CustomProperties") { + /** + * Fetches the property of the ModelProperty component on the entity. + */ + inline fun <reified T> getProperty(key: String): T? { + return when (T::class) { + String::class -> getStringProperty(id.id, key) as T? + Long::class -> getLongProperty(id.id, key) as T? + Int::class -> getIntProperty(id.id, key) as T? + Double::class -> getDoubleProperty(id.id, key) as T? + + Float::class -> getFloatProperty(id.id, key) as T? + Boolean::class -> getBoolProperty(id.id, key) as T? + FloatArray::class -> getVec3Property(id.id, key) as T? + else -> throw IllegalArgumentException("Unsupported property type: ${T::class}") + } + } + + /** + * Sets a property of the ModelProperty component on the entity. + * + * # Supported types + * - [kotlin.String] + * - [kotlin.Long] + * - [kotlin.Int] + * - [kotlin.Double] + * - [kotlin.Float] + * - [kotlin.Boolean] + * - [com.dropbear.math.Vector3] + */ + /** + * Sets a property of the ModelProperty component on the entity. + * + * # Supported types + * - [kotlin.String] + * - [kotlin.Long] + * - [kotlin.Int] + * - [kotlin.Double] + * - [kotlin.Float] + * - [kotlin.Boolean] + * - [com.dropbear.math.Vector3] + */ + fun setProperty(key: String, value: Any) { + when (value) { + is String -> setStringProperty(id.id, key, value) + is Long -> setLongProperty(id.id, key, value) + is Int -> setIntProperty(id.id, key, value) + is Double -> setFloatProperty(id.id, key, value) + is Float -> setFloatProperty(id.id, key, value.toDouble()) + is Boolean -> setBoolProperty(id.id, key, value) + is Vector3<*> -> { + val vec = value.asDoubleVector() + setVec3Property(id.id, key, floatArrayOf(vec.x.toFloat(), vec.y.toFloat(), + vec.z.toFloat() + )) + } + is FloatArray -> { + require(value.size == 3) { "Vec3 property must have exactly 3 elements" } + setVec3Property(id.id, key, value) + } + else -> throw IllegalArgumentException("Unsupported property type: ${value::class}") + } + } + + companion object : ComponentType<CustomProperties> { + override fun get(entityId: EntityId): CustomProperties? { + return if (customPropertiesExistsForEntity(entityId)) CustomProperties(entityId) else null + } + } +} + +expect fun CustomProperties.getStringProperty(entityHandle: Long, label: String): String? +expect fun CustomProperties.getIntProperty(entityHandle: Long, label: String): Int? +expect fun CustomProperties.getLongProperty(entityHandle: Long, label: String): Long? +expect fun CustomProperties.getDoubleProperty(entityHandle: Long, label: String): Double? +expect fun CustomProperties.getFloatProperty(entityHandle: Long, label: String): Float? +expect fun CustomProperties.getBoolProperty(entityHandle: Long, label: String): Boolean? +expect fun CustomProperties.getVec3Property(entityHandle: Long, label: String): FloatArray? + +expect fun CustomProperties.setStringProperty(entityHandle: Long, label: String, value: String) +expect fun CustomProperties.setIntProperty(entityHandle: Long, label: String, value: Int) +expect fun CustomProperties.setLongProperty(entityHandle: Long, label: String, value: Long) +expect fun CustomProperties.setFloatProperty(entityHandle: Long, label: String, value: Double) +expect fun CustomProperties.setBoolProperty(entityHandle: Long, label: String, value: Boolean) +expect fun CustomProperties.setVec3Property(entityHandle: Long, label: String, value: FloatArray) + +expect fun customPropertiesExistsForEntity(entityId: EntityId): Boolean @@ -5,7 +5,6 @@ import com.dropbear.ffi.NativeEngine import com.dropbear.input.InputState import com.dropbear.logging.Logger import com.dropbear.scene.SceneManager -import com.dropbear.ui.UIManager internal var exceptionOnError: Boolean = false var lastErrorMessage: String? = null @@ -18,8 +17,21 @@ var lastErrorMessage: String? = null */ class DropbearEngine(val native: NativeEngine) { private var inputState: InputState? = null + get() { + if (field == null) { + Logger.trace("InputState not initialised, creating new one") + field = InputState() + } + return field + } private var sceneManager: SceneManager? = null - private var uiManager: UIManager? = null + get() { + if (field == null) { + Logger.trace("SceneManager not initialised, creating new one") + field = SceneManager() + } + return field + } init { Companion.native = native @@ -46,57 +58,12 @@ class DropbearEngine(val native: NativeEngine) { * Fetches an [EntityRef] with the given label. */ fun getEntity(label: String): EntityRef? { - val entityId = native.getEntity(label) + val entityId = com.dropbear.getEntity(label) val entityRef = if (entityId != null) EntityRef(EntityId(entityId)) else null - entityRef?.engine = this return entityRef } /** - * Fetches the information of the camera with the given label. - */ - fun getCamera(label: String): Camera? { - val result = native.getCamera(label) - if (result != null) { - result.engine = this - } - return result - } - - /** - * Gets the current [InputState] for that frame. - */ - fun getInputState(): InputState { - if (this.inputState == null) { - Logger.trace("InputState not initialised, creating new one") - this.inputState = InputState(native) - } - return this.inputState!! - } - - /** - * Gets the current [SceneManager] for that frame. - */ - fun getSceneManager(): SceneManager { - if (this.sceneManager == null) { - Logger.trace("SceneManager not initialised, creating new one") - this.sceneManager = SceneManager(native) - } - return this.sceneManager!! - } - - /** - * Gets the current [UIManager] for that frame. - */ - fun getUIManager(): UIManager { - if (this.uiManager == null) { - Logger.trace("UiManager not initialised, creating new one") - this.uiManager = UIManager(native) - } - return this.uiManager!! - } - - /** * Fetches the asset information from the internal AssetRegistry (located in * `dropbear_engine::asset::AssetRegistry`). * @@ -104,7 +71,7 @@ class DropbearEngine(val native: NativeEngine) { * The eucalyptus asset URI (or `euca://`) is case-sensitive. */ fun getAsset(eucaURI: String): AssetHandle? { - val id = native.getAsset(eucaURI) + val id = com.dropbear.getAsset(eucaURI) return if (id != null) AssetHandle(id) else null } @@ -116,7 +83,7 @@ class DropbearEngine(val native: NativeEngine) { fun callExceptionOnError(toggle: Boolean) = DropbearEngine.callExceptionOnError(toggle) /** - * Quits the currently running app or game. + * Quits the currently running app or game elegantly. * * This function can have different behaviours depending on where it is ran. * - eucalyptus-editor - When called, this exits your Play Mode session and returns you back to @@ -125,6 +92,11 @@ class DropbearEngine(val native: NativeEngine) { * also drop any pointers and do any additional cleanup. */ fun quit() { - native.quit() + com.dropbear.quit() } -} +} + +expect fun getEntity(label: String): Long? +expect fun getCamera(label: String): Camera? +expect fun getAsset(eucaURI: String): Long? +expect fun quit() @@ -1,12 +1,7 @@ package com.dropbear -import com.dropbear.asset.ModelHandle -import com.dropbear.asset.TextureHandle -import com.dropbear.math.Transform -import com.dropbear.math.Vector3 -import com.dropbear.math.Vector3D -import com.dropbear.physics.Collider -import com.dropbear.physics.RigidBody +import com.dropbear.ecs.Component +import com.dropbear.ecs.ComponentType /** * A reference to an ECS Entity stored inside the dropbear engine. @@ -21,172 +16,21 @@ import com.dropbear.physics.RigidBody * playthroughs, so it is recommended not to store this value. */ class EntityRef(val id: EntityId = EntityId(0L)) { - lateinit var engine: DropbearEngine - - override fun toString(): String { - return "EntityRef(id=$id)" - } - - /** - * Fetches the [EntityTransform] component for the entity. - */ - fun getTransform(): EntityTransform? { - return engine.native.getTransform(id) - } - - /** - * Walks up the world hierarchy to find the transform of the parent, then multiply - * to create a propagated [Transform]. - * - * This will update the entity's world transform based on its parent's world transform. - */ - fun propagate(): Transform? { - return engine.native.propagateTransform(id) - } - - /** - * Sets and replaces the [EntityTransform] component for the entity. - */ - fun setTransform(transform: EntityTransform?) { - if (transform == null) return - return engine.native.setTransform(id, transform) - } - - /** - * Fetches the property of the ModelProperty component on the entity. - */ - inline fun <reified T> getProperty(key: String): T? { - return when (T::class) { - String::class -> engine.native.getStringProperty(id.id, key) as T? - Long::class -> engine.native.getLongProperty(id.id, key) as T? - Int::class -> engine.native.getIntProperty(id.id, key) as T? - Double::class -> engine.native.getDoubleProperty(id.id, key) as T? - - Float::class -> engine.native.getFloatProperty(id.id, key) as T? - Boolean::class -> engine.native.getBoolProperty(id.id, key) as T? - FloatArray::class -> engine.native.getVec3Property(id.id, key) as T? - else -> throw IllegalArgumentException("Unsupported property type: ${T::class}") - } - } - /** - * Sets a property of the ModelProperty component on the entity. + * The `Label` component (the entity name). * - * # Supported types - * - [kotlin.String] - * - [kotlin.Long] - * - [kotlin.Int] - * - [kotlin.Double] - * - [kotlin.Float] - * - [kotlin.Boolean] - * - [com.dropbear.math.Vector3] - */ - /** - * Sets a property of the ModelProperty component on the entity. - * - * # Supported types - * - [kotlin.String] - * - [kotlin.Long] - * - [kotlin.Int] - * - [kotlin.Double] - * - [kotlin.Float] - * - [kotlin.Boolean] - * - [com.dropbear.math.Vector3] - */ - fun setProperty(key: String, value: Any) { - when (value) { - is String -> engine.native.setStringProperty(id.id, key, value) - is Long -> engine.native.setLongProperty(id.id, key, value) - is Int -> engine.native.setIntProperty(id.id, key, value) - is Double -> engine.native.setFloatProperty(id.id, key, value) - is Float -> engine.native.setFloatProperty(id.id, key, value.toDouble()) - is Boolean -> engine.native.setBoolProperty(id.id, key, value) - is Vector3<*> -> { - val vec = value.asDoubleVector() - engine.native.setVec3Property(id.id, key, floatArrayOf(vec.x.toFloat(), vec.y.toFloat(), - vec.z.toFloat() - )) - } - is FloatArray -> { - require(value.size == 3) { "Vec3 property must have exactly 3 elements" } - engine.native.setVec3Property(id.id, key, value) - } - else -> throw IllegalArgumentException("Unsupported property type: ${value::class}") - } - } - - /** - * Fetches the attached camera for the entity. - * - * Returns null if no camera is attached as a component according to the editor. - */ - fun getAttachedCamera(): Camera? { - val result = engine.native.getAttachedCamera(id) - if (result != null) { - result.engine = this.engine - } - return result - } - - /** - * Fetches the texture for the given material name in the model. - */ - fun getTexture(materialName: String): TextureHandle? { - val result = engine.native.getTexture(id.id, materialName) - return if (result == null) { - null - } else { - TextureHandle(result) - } - } - - /** - * Returns an array containing the texture identifiers applied to this entity's model. - */ - fun getAllTextures(): Array<String> { - return engine.native.getAllTextures(id.id) - } - - /** - * Checks if the current model being rendered by this entity contains the texture with the given [TextureHandle] - */ - fun hasTexture(textureHandle: TextureHandle): Boolean { - return engine.native.isUsingTexture(id.id, textureHandle.raw()) - } - - /** - * Fetches the active model that is currently being used - */ - fun getModel(): ModelHandle? { - val result = engine.native.getModel(id.id) - return if (result == null) { - null - } else { - ModelHandle(result) - } - } - - /** - * Sets the active model for the entity from a ModelHandle + * All entities have a `Label` component. If one does not, it is considered a bug in the engine or *you* did something + * to break this. Anyhow, it will throw an [Exception]. */ - fun setModel(modelHandle: ModelHandle) { - engine.native.setModel(id.id, modelHandle.raw()) - } + val label: String + get() = getEntityLabel(id) ?: throw Exception("Entity has no label, expected to contain") - /** - * Checks if the entity is currently using the given model handle. - * - * Returns false if not using, true if is. - */ - fun usingModel(modelHandle: ModelHandle): Boolean { - return engine.native.isUsingModel(id.id, modelHandle.raw()) + override fun toString(): String { + return "EntityRef(id=$id)" } - /** - * Sets a texture override for the given material on the active model. - */ - fun setTextureOverride(materialName: String, textureHandle: TextureHandle) { - engine.native.setTextureOverride(id.id, materialName, textureHandle) + fun <T : Component> get(type: ComponentType<T>): T? { + return type.get(id) } /** @@ -204,7 +48,7 @@ class EntityRef(val id: EntityId = EntityId(0L)) { * By running [getChildren] on `cat`, it will return `[ wizard_hat ]`, not `pom_pom`. */ fun getChildren(): Array<EntityRef>? { - return engine.native.getChildren(id) + return getChildren(id) } /** @@ -213,7 +57,7 @@ class EntityRef(val id: EntityId = EntityId(0L)) { * Returns `null` if an error occurred or no child exists, otherwise the entity. */ fun getChildByLabel(label: String): EntityRef? { - return engine.native.getChildByLabel(id, label) + return getChildByLabel(id, label) } /** @@ -232,60 +76,11 @@ class EntityRef(val id: EntityId = EntityId(0L)) { * Calling [getParent] on `cat` will return `null`, as the Scene is not an entity. */ fun getParent(): EntityRef? { - return engine.native.getParent(id) - } - - /** - * Fetches the `Label` component (the entity name). - * - * All entities have a `Label` component. If one does not, it is considered a bug in the engine or *you* did something - * to break this. Anyhow, it will throw an [Exception]. - */ - fun getLabel(): String { - return engine.native.getEntityLabel(id.id) ?: throw Exception("Entity has no label, expected to contain. Likely engine bug") - } - - // physics stuff - - /** - * Sets physics enabled. - * - * If physics is enabled, the entity will be under the influence of gravity. Using position based movement will - * not be possible, and will have to be done with physics based movement. - * - * If physics is disabled, the entity will **not** be under the influence of gravity and will stand still. - * Other physic-based entities (such as walls and floors) will not affect the player, and collision based - * functions will not work. - */ - fun setPhysicsEnabled(enabled: Boolean) { - return engine.native.setPhysicsEnabled(id.id, enabled) - } - - /** - * Checks if physics is applied to the entity. - * - * If physics is enabled, it will return true. If not, it will return false. - */ - fun isPhysicsEnabled(): Boolean { - return engine.native.isPhysicsEnabled(id.id) + return getParent(id) } +} - /** - * Fetches the [`RigidBody`] component. - * - * Can return `null` if no component exists within the entity. - */ - fun getRigidBody(): RigidBody? { - return engine.native.getRigidBody(id.id) - } - - /** - * Fetches all available colliders under the `ColliderGroup` component of the entity. - * - * Can return an [emptyArray] if no Collider's exist within the group, or `null` if no - * such component (`ColliderGroup`) is available on the entity. - */ - fun getAllColliders(): List<Collider>? { - return engine.native.getAllColliders(id.id) - } -} +expect fun EntityRef.getEntityLabel(entity: EntityId): String? +expect fun EntityRef.getChildren(entityId: EntityId): Array<EntityRef>? +expect fun EntityRef.getChildByLabel(entityId: EntityId, label: String): EntityRef? +expect fun EntityRef.getParent(entityId: EntityId): EntityRef? @@ -1,12 +1,59 @@ package com.dropbear +import com.dropbear.ecs.Component +import com.dropbear.ecs.ComponentType import com.dropbear.math.Transform /** * A component that contains the local and world [Transform] of an entity. */ -class EntityTransform(var local: Transform, var world: Transform) { +class EntityTransform(val id: EntityId): Component(id, "EntityTransform") { + var local: Transform + get() = getLocalTransform(id) + set(value) = setLocalTransform(id, value) + var world: Transform + get() = getWorldTransform(id) + set(value) = setWorldTransform(id, value) + override fun toString(): String { - return "EntityTransform(local=$local, world=$world)" + return "EntityTransform(id: $id, local=$local, world=$world)" + } + + /** + * Walks up the world hierarchy to find the transform of the parent, then multiply/add + * to create a propagated [Transform]. + */ + fun propagate(): Transform { + return propagateTransform(id) + } + + /** + * Merges the local and world transforms and return the merged [Transform] + */ + fun sync(): Transform { + val scaledPos = local.position * world.scale + val rotatedPos = world.rotation * scaledPos + val finalPos = world.position + rotatedPos + val finalRot = world.rotation * local.rotation + val finalScale = world.scale * local.scale + return Transform(finalPos, finalRot, finalScale) } -} + + companion object : ComponentType<EntityTransform> { + override fun get(entityId: EntityId): EntityTransform? { + return if (entityTransformExistsForEntity(entityId)) { + EntityTransform(entityId) + } else { + null + } + } + } +} + +expect fun EntityTransform.getLocalTransform(entityId: EntityId): Transform +expect fun EntityTransform.setLocalTransform(entityId: EntityId, transform: Transform) +expect fun EntityTransform.getWorldTransform(entityId: EntityId): Transform +expect fun EntityTransform.setWorldTransform(entityId: EntityId, transform: Transform) +expect fun EntityTransform.propagateTransform(entityId: EntityId): Transform + +expect fun entityTransformExistsForEntity(entityId: EntityId): Boolean @@ -0,0 +1,72 @@ +package com.dropbear + +import com.dropbear.asset.ModelHandle +import com.dropbear.asset.TextureHandle +import com.dropbear.ecs.Component +import com.dropbear.ecs.ComponentType + +class MeshRenderer(val id: EntityId) : Component(id, "MeshRenderer") { + + /** + * The active model currently assigned to this entity. + * Setting this to null removes the model. + * + * Usage: + * ``` + * val handle = renderer.model + * renderer.model = newHandle + * ``` + */ + var model: ModelHandle? + get() { + return getModel(id) + } + set(value) { + setModel(id, value) + } + + /** + * A list of all active Texture handles currently applied to the model. + */ + val textures: List<TextureHandle>? + get() = getAllTextureIds(id) + + /** + * Returns a list of material names available on the current model. + * Useful for knowing what keys to use in [getTexture] or [setTextureOverride]. + */ + val materialNames: List<String> + get() = getMaterialNames(id) + + /** + * Fetches the texture assigned to a specific material slot. + * Returns null if the material doesn't exist or has no texture. + */ + fun getTexture(materialName: String): TextureHandle? { + val rawId = getTexture(id, materialName) + return if (rawId == 0L) null else TextureHandle(rawId) + } + + /** + * Overrides the texture for a specific material on the active model. + */ + fun setTextureOverride(materialName: String, textureHandle: TextureHandle) { + setTextureOverride(id, materialName, textureHandle.raw()) + } + + companion object : ComponentType<MeshRenderer> { + override fun get(entityId: EntityId): MeshRenderer? { + return if (meshRendererExistsForEntity(entityId)) MeshRenderer(entityId) else null + } + } +} + +expect fun MeshRenderer.getModel(id: EntityId): ModelHandle? +expect fun MeshRenderer.setModel(id: EntityId, model: ModelHandle?) +expect fun MeshRenderer.getAllTextureIds(id: EntityId): List<TextureHandle>? +expect fun MeshRenderer.getMaterialNames(id: EntityId): List<String> +expect fun MeshRenderer.setMaterialNames(id: EntityId, names: Array<String>) +expect fun MeshRenderer.getTexture(id: EntityId, materialName: String): Long +expect fun MeshRenderer.setTextureOverride(id: EntityId, materialName: String, textureHandle: Long) + +expect fun meshRendererExistsForEntity(entityId: EntityId): Boolean @@ -7,7 +7,10 @@ package com.dropbear * the `magna-carta` manifest generator tool. * * The tags correspond to the tags provided to the entity - * with the Script. + * with the Script. + * + * # Note + * This annotation only works on classes that implement [com.dropbear.ecs.System], **not** [com.dropbear.ecs.Component] */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) @@ -1,5 +1,10 @@ package com.dropbear +import com.dropbear.ecs.System + +/** + * Internal data class to register scripts with tags. + */ data class ScriptRegistration( val tags: List<String>, val script: System @@ -1,93 +0,0 @@ -package com.dropbear - -/** - * A class that contains the basic information of a system. - * - * The dropbear engine follows an ECS paradigm, with logic being - * provided as Systems. - */ -open class System { - /** - * The current entity that is being run in the system. Most often than not, it - * will have an [EntityRef] attached (because all Script components must be part - * of an entity). - */ - var currentEntity: EntityRef? = null - private set - - private var engineRef: DropbearEngine? = null - - /** - * This function is called when the script module is initialised. - * - * It is only called once during scene execution. If you re-switch back - * to this scene after running the class, it will be run again. - */ - open fun load(engine: DropbearEngine) {} - - /** - * This function is called for each update. - * - * It is run once for each frame, and for every frame. Since this is synced to the frame rate, using - * the [deltaTime] variable can aid you in creating uniform player speeds (or something like that). - * - * @param deltaTime - This specifies the time elapsed since the last update. - */ - open fun update(engine: DropbearEngine, deltaTime: Float) {} - - /** - * This function is called for each update that is related to physics. - * - * It can be run 0, 1, 2 or more times per frame. Updating physics is done at a constant - * rate/tick (at roughly 50Hz or 0.02), which is why it is not ran as often as a standard [update]. - * - * @param deltaTime - This specifies the time elapsed since the last frame update. Likely, it's going - * to be somewhere around 50Hz. For the most part, you might not need this. - */ - open fun physicsUpdate(engine: DropbearEngine, deltaTime: Float) {} - - /** - * This function is called at the end of the script execution. - * - * It is run at the end of execution of a scene, such as when the scene switches. It is also ran once throughout - * the lifecycle of a script class. It is best to think about it like `sceneExit()` instead of `appExit()` - * - * It would be used to clean up any memory related resources (such as `SceneLoadHandle` or any memory related items). - * - * # Note - * - * The script module does not lose state (such as variables) when destroyed. It is cached internally (within the system manager), - * therefore counters and other related stuff will not lose track. - */ - open fun destroy(engine: DropbearEngine) {} - - /** - * Internal: This attaches the [DropbearEngine] fascade (typically created through some external location) - * to the existing system to be used. - */ - fun attachEngine(engine: DropbearEngine) { - engineRef = engine - currentEntity?.engine = engine - } - - /** - * Internal: Sets the current entity of this [System] to something. - */ - fun setCurrentEntity(entity: Long) { - val engine = engineRef ?: run { - currentEntity = null - return - } - - val reference = EntityRef(EntityId(entity)) - reference.engine = engine - currentEntity = reference - } - - /** - * Internal: Clears the current entity used. - */ - fun clearCurrentEntity() { - currentEntity = null - } -} @@ -11,8 +11,8 @@ class AssetHandle(private val id: Long): Handle(id) { * * It can return null if the asset is not a model. */ - fun asModelHandle(engine: DropbearEngine): ModelHandle? { - val result = engine.native.isModelHandle(id) + fun asModelHandle(): ModelHandle? { + val result = isModelHandle(id) return if (result) { ModelHandle(id) } else { @@ -20,20 +20,6 @@ class AssetHandle(private val id: Long): Handle(id) { } } - /** - * Converts an [AssetHandle] to a [TextureHandle]. - * - * It can return null if the asset is not a texture. - */ - fun asTextureHandle(engine: DropbearEngine): TextureHandle? { - val result = engine.native.isTextureHandle(id) - return if (result) { - TextureHandle(id) - } else { - null - } - } - override fun asAssetHandle(): AssetHandle { return this } @@ -41,4 +27,13 @@ class AssetHandle(private val id: Long): Handle(id) { override fun toString(): String { return "AssetHandle(id=$id)" } -} +} + +/** + * Converts an [AssetHandle] to a [TextureHandle]. + * + * It can return null if the asset is not a texture. + */ +expect fun AssetHandle.asTextureHandle(): TextureHandle? + +expect fun isModelHandle(id: Long): Boolean @@ -12,11 +12,13 @@ class TextureHandle(private val id: Long): Handle(id) { /** * Fetches the name of that specific texture */ - fun getName(engine: DropbearEngine): String? { - return engine.native.getTextureName(id) + fun getName(): String? { + return getTextureName(id) } override fun toString(): String { return "TextureHandle(id=$id)" } -} +} + +expect fun TextureHandle.getTextureName(id: Long): String? @@ -0,0 +1,24 @@ +package com.dropbear.ecs + +import com.dropbear.EntityId + +/** + * A custom property that *can* be attached to an entity in the dropbear ECS system. + * + * @param parentEntity - The [com.dropbear.EntityId] to which this component is attached. + * @param typeName - The string name of the component type as defined in Rust. The name is + * found as the type name, such as `component_registry.register_with_default::<Camera3D>();`, + * where the type name would be `"Camera3D"`. + */ +abstract class Component( + val parentEntity: EntityId, + val typeName: String, +) { + override fun toString(): String { + return "Component(parentEntity: ${this.parentEntity}, typeName: $typeName)" + } +} + +interface ComponentType<T : Component> { + fun get(entityId: EntityId): T? +} @@ -0,0 +1,90 @@ +package com.dropbear.ecs + +import com.dropbear.DropbearEngine +import com.dropbear.EntityId +import com.dropbear.EntityRef + +/** + * A class that contains the basic information of a system. + * + * The dropbear engine follows an ECS paradigm, with logic being + * provided as Systems. + */ +open class System { + /** + * The current entity that is being run in the system. Most often than not, it + * will have an [com.dropbear.EntityRef] attached (because all Script components must be part + * of an entity). + */ + var currentEntity: EntityRef? = null + private set + + private var engineRef: DropbearEngine? = null + + /** + * This function is called when the script module is initialised. + * + * It is only called once during scene execution. If you re-switch back + * to this scene after running the class, it will be run again. + */ + open fun load(engine: DropbearEngine) {} + + /** + * This function is called for each update. + * + * It is run once for each frame, and for every frame. Since this is synced to the frame rate, using + * the [deltaTime] variable can aid you in creating uniform player speeds (or something like that). + * + * @param deltaTime - This specifies the time elapsed since the last update. + */ + open fun update(engine: DropbearEngine, deltaTime: Float) {} + + /** + * This function is called for each update that is related to physics. + * + * It can be run 0, 1, 2 or more times per frame. Updating physics is done at a constant + * rate/tick (at roughly 50Hz or 0.02), which is why it is not ran as often as a standard [update]. + * + * @param deltaTime - This specifies the time elapsed since the last frame update. Likely, it's going + * to be somewhere around 50Hz. For the most part, you might not need this. + */ + open fun physicsUpdate(engine: DropbearEngine, deltaTime: Float) {} + + /** + * This function is called at the end of the script execution. + * + * It is run at the end of execution of a scene, such as when the scene switches. It is also ran once throughout + * the lifecycle of a script class. It is best to think about it like `sceneExit()` instead of `appExit()` + * + * It would be used to clean up any memory related resources (such as `SceneLoadHandle` or any memory related items). + * + * # Note + * + * The script module does not lose state (such as variables) when destroyed. It is cached internally (within the system manager), + * therefore counters and other related stuff will not lose track. + */ + open fun destroy(engine: DropbearEngine) {} + + /** + * Internal: This attaches the [DropbearEngine] fascade (typically created through some external location) + * to the existing system to be used. + */ + fun attachEngine(engine: DropbearEngine) { + engineRef = engine + } + + /** + * Internal: Sets the current entity of this [System] to something. + */ + fun setCurrentEntity(entity: Long) { + val reference = EntityRef(EntityId(entity)) + currentEntity = reference + } + + /** + * Internal: Clears the current entity used. + */ + fun clearCurrentEntity() { + currentEntity = null + } +} @@ -1,4 +0,0 @@ -package com.dropbear.ffi - -expect fun getEntity(label: String): Long? -expect fun getAsset(eucaURI: String): Long? @@ -1,123 +1,9 @@ package com.dropbear.ffi -import com.dropbear.Camera -import com.dropbear.EntityId -import com.dropbear.EntityRef -import com.dropbear.EntityTransform -import com.dropbear.asset.AssetHandle -import com.dropbear.asset.ModelHandle -import com.dropbear.asset.TextureHandle -import com.dropbear.input.Gamepad -import com.dropbear.input.GamepadButton -import com.dropbear.input.KeyCode -import com.dropbear.input.MouseButton -import com.dropbear.math.Transform -import com.dropbear.math.Vector2D -import com.dropbear.math.Vector3D -import com.dropbear.physics.Collider -import com.dropbear.physics.Index -import com.dropbear.physics.RigidBody -import com.dropbear.scene.SceneLoadHandle -import com.dropbear.scene.SceneLoadStatus -import com.dropbear.utils.Progress - /** - * Native functions + * Native information about dropbear engine. * - * Class that describes all the functions that can - * be communicated with the `eucalyptus_core` dynamic library + * This class contains handles to various native subsystems such as world, input, graphics, and more. Different + * targets (JVM, Native) will have different implementations for managing these handles. Check them out! */ -expect class NativeEngine { - fun getEntity(label: String): Long? - fun getAsset(eucaURI: String): Long? - - fun getEntityLabel(entityHandle: Long): String? - - fun getModel(entityHandle: Long): Long? - fun setModel(entityHandle: Long, modelHandle: Long) - fun isUsingModel(entityHandle: Long, modelHandle: Long): Boolean - fun isModelHandle(id: Long): Boolean - - fun getTexture(entityHandle: Long, name: String): Long? - fun setTextureOverride(entityHandle: Long, oldMaterialName: String, newTextureHandle: TextureHandle) - fun isUsingTexture(entityHandle: Long, textureHandle: Long): Boolean - fun isTextureHandle(id: Long): Boolean - fun getTextureName(textureHandle: Long): String? - fun getAllTextures(entityHandle: Long): Array<String> - - fun getCamera(label: String): Camera? - fun getAttachedCamera(entityId: EntityId): Camera? - fun setCamera(camera: Camera); - - fun getTransform(entityId: EntityId): EntityTransform? - fun propagateTransform(entityId: EntityId): Transform? - fun setTransform(entityId: EntityId, transform: EntityTransform) - - fun getChildren(entityId: EntityId): Array<EntityRef>? - fun getChildByLabel(entityId: EntityId, label: String): EntityRef? - fun getParent(entityId: EntityId): EntityRef? - - fun switchToSceneImmediate(sceneName: String) - fun loadSceneAsync(sceneName: String): SceneLoadHandle? - fun loadSceneAsync(sceneName: String, loadingScene: String): SceneLoadHandle? - fun switchToSceneAsync(sceneLoadHandle: SceneLoadHandle) - fun getSceneLoadProgress(sceneLoadHandle: SceneLoadHandle): Progress - fun getSceneLoadStatus(sceneLoadHandle: SceneLoadHandle): SceneLoadStatus - - // ------------------------ MODEL PROPERTIES ------------------------- - - fun getStringProperty(entityHandle: Long, label: String): String? - fun getIntProperty(entityHandle: Long, label: String): Int? - fun getLongProperty(entityHandle: Long, label: String): Long? - fun getDoubleProperty(entityHandle: Long, label: String): Double? - fun getFloatProperty(entityHandle: Long, label: String): Float? - fun getBoolProperty(entityHandle: Long, label: String): Boolean? - fun getVec3Property(entityHandle: Long, label: String): FloatArray? - - fun setStringProperty(entityHandle: Long, label: String, value: String) - fun setIntProperty(entityHandle: Long, label: String, value: Int) - fun setLongProperty(entityHandle: Long, label: String, value: Long) - fun setFloatProperty(entityHandle: Long, label: String, value: Double) - fun setBoolProperty(entityHandle: Long, label: String, value: Boolean) - fun setVec3Property(entityHandle: Long, label: String, value: FloatArray) - - - // --------------------------- INPUT STATE --------------------------- - - /** - * Prints the input state, typically used for debugging. - */ - fun printInputState() - fun isKeyPressed(key: KeyCode): Boolean - fun getMousePosition(): Vector2D? - fun isMouseButtonPressed(button: MouseButton): Boolean - fun getMouseDelta(): Vector2D? - fun isCursorLocked(): Boolean - fun setCursorLocked(locked: Boolean) - fun isCursorHidden(): Boolean - fun setCursorHidden(hidden: Boolean) - fun getLastMousePos(): Vector2D? - fun getConnectedGamepads(): List<Gamepad> - fun isGamepadButtonPressed(id: Long, button: GamepadButton): Boolean - - // ------------------------------------------------------------------- - - // physics stuff - - // EntityRef.kt - fun setPhysicsEnabled(entityId: Long, enabled: Boolean) - fun isPhysicsEnabled(entityId: Long): Boolean - fun getRigidBody(entityId: Long): RigidBody? - fun getAllColliders(entityId: Long): List<Collider> - - // physics/RigidBody.kt - fun applyImpulse(index: Index, x: Double, y: Double, z: Double) - fun applyTorqueImpulse(index: Index, x: Double, y: Double, z: Double) - fun setRigidbody(rigidBody: RigidBody) - fun getChildColliders(index: Index): List<Collider> - - // physics/Collider.kt - fun setCollider(collider: Collider) - - fun quit() -} +expect class NativeEngine @@ -10,13 +10,14 @@ class Gamepad( val id: Long, val leftStickPosition: Vector2D, val rightStickPosition: Vector2D, - val native: NativeEngine, ) { fun isButtonPressed(button: GamepadButton): Boolean { - return native.isGamepadButtonPressed(id, button) + return isGamepadButtonPressed(id, button) } override fun toString(): String { return "Gamepad $id @ ($leftStickPosition ; $rightStickPosition)" } -} +} + +expect fun Gamepad.isGamepadButtonPressed(id: Long, button: GamepadButton): Boolean @@ -13,49 +13,16 @@ import com.dropbear.math.Vector2D * The InputState does not have any values that can be mutated, only * queried. */ -class InputState(private val native: NativeEngine) { - - fun printInputState() { - native.printInputState() - } - - fun isKeyPressed(key: KeyCode): Boolean { - return native.isKeyPressed(key) - } - - fun getMousePosition(): Vector2D { - return native.getMousePosition() ?: Vector2D(0.0, 0.0) - } - - fun isMouseButtonPressed(button: MouseButton): Boolean { - return native.isMouseButtonPressed(button) - } - - fun getMouseDelta(): Vector2D { - return native.getMouseDelta() ?: Vector2D(0.0, 0.0) - } - - fun isCursorLocked(): Boolean { - return native.isCursorLocked() - } - - fun setCursorLocked(locked: Boolean) { - return native.setCursorLocked(locked) - } - - fun getLastMousePos(): Vector2D { - return native.getLastMousePos() ?: Vector2D(0.0, 0.0) - } - - fun isCursorHidden(): Boolean { - return native.isCursorHidden() - } - - fun setCursorHidden(hidden: Boolean) { - return native.setCursorHidden(hidden) - } - - fun getConnectedGamepads(): List<Gamepad> { - return native.getConnectedGamepads() - } +expect class InputState() { + fun printInputState() + fun isKeyPressed(key: KeyCode): Boolean + fun getMousePosition(): Vector2D + fun isMouseButtonPressed(button: MouseButton): Boolean + fun getMouseDelta(): Vector2D + fun isCursorLocked(): Boolean + fun setCursorLocked(locked: Boolean) + fun getLastMousePos(): Vector2D + fun isCursorHidden(): Boolean + fun setCursorHidden(hidden: Boolean) + fun getConnectedGamepads(): List<Gamepad> } @@ -1,37 +1,52 @@ package com.dropbear.physics import com.dropbear.EntityId -import com.dropbear.ffi.NativeEngine import com.dropbear.math.Vector3D class Collider( internal val index: Index, internal val entity: EntityId, internal val id: UInt, - internal val native: NativeEngine ) { var colliderShape: ColliderShape - get() = native.getColliderShape(this) - set(value) = native.setColliderShape(this, value) + get() = getColliderShape(this) + set(value) = setColliderShape(this, value) var density: Double - get() = native.getColliderDensity(this) - set(value) = native.setColliderDensity(this, value) + get() = getColliderDensity(this) + set(value) = setColliderDensity(this, value) var friction: Double - get() = native.getColliderFriction(this) - set(value) = native.setColliderFriction(this, value) + get() = getColliderFriction(this) + set(value) = setColliderFriction(this, value) var restitution: Double - get() = native.getColliderRestitution(this) - set(value) = native.setColliderRestitution(this, value) + get() = getColliderRestitution(this) + set(value) = setColliderRestitution(this, value) var isSensor: Boolean - get() = native.getColliderIsSensor(this) - set(value) = native.setColliderIsSensor(this, value) + get() = getColliderIsSensor(this) + set(value) = setColliderIsSensor(this, value) var translation: Vector3D - get() = native.getColliderTranslation(this) - set(value) = native.setColliderTranslation(this, value) + get() = getColliderTranslation(this) + set(value) = setColliderTranslation(this, value) var rotation: Vector3D - get() = native.getColliderRotation(this) - set(value) = native.setColliderRotation(this, value) + get() = getColliderRotation(this) + set(value) = setColliderRotation(this, value) var mass: Double - get() = native.getColliderMass(this) - set(value) = native.setColliderMass(this, value) -} + get() = getColliderMass(this) + set(value) = setColliderMass(this, value) +} + +expect fun Collider.getColliderShape(collider: Collider): ColliderShape +expect fun Collider.setColliderShape(collider: Collider, shape: ColliderShape) +expect fun Collider.getColliderDensity(collider: Collider): Double +expect fun Collider.setColliderDensity(collider: Collider, density: Double) +expect fun Collider.getColliderFriction(collider: Collider): Double +expect fun Collider.setColliderFriction(collider: Collider, friction: Double) +expect fun Collider.getColliderRestitution(collider: Collider): Double +expect fun Collider.setColliderRestitution(collider: Collider, restitution: Double) +expect fun Collider.getColliderIsSensor(collider: Collider): Boolean +expect fun Collider.setColliderIsSensor(collider: Collider, isSensor: Boolean) +expect fun Collider.getColliderTranslation(collider: Collider): Vector3D +expect fun Collider.setColliderTranslation(collider: Collider, translation: Vector3D) +expect fun Collider.getColliderRotation(collider: Collider): Vector3D +expect fun Collider.setColliderRotation(collider: Collider, rotation: Vector3D) +expect fun Collider.getColliderMass(collider: Collider): Double +expect fun Collider.setColliderMass(collider: Collider, mass: Double) @@ -0,0 +1,23 @@ +package com.dropbear.physics + +import com.dropbear.ecs.Component +import com.dropbear.EntityId +import com.dropbear.ecs.ComponentType + +class ColliderGroup( + entity: EntityId, +) : Component(entity, "ColliderGroup") { + fun getColliders(): List<Collider> { + return getColliderGroupColliders(this) + } + + companion object : ComponentType<ColliderGroup> { + override fun get(entityId: EntityId): ColliderGroup? { + return if (colliderGroupExistsForEntity(entityId)) ColliderGroup(entityId) else null + } + } +} + +expect fun ColliderGroup.getColliderGroupColliders(colliderGroup: ColliderGroup): List<Collider> + +expect fun colliderGroupExistsForEntity(entityId: EntityId): Boolean @@ -1,80 +1,30 @@ package com.dropbear.physics import com.dropbear.math.Vector3D -import kotlin.math.PI -import kotlin.math.pow sealed class ColliderShape { /** * Box shape with half-extents (half-width, half-height, half-depth). */ - data class Box(val halfExtents: Vector3D) : ColliderShape() { - /** - * Returns the volume of the shape/box. - * - * In this case, volume is calculated as: [halfExtents].x * [halfExtents].y * [halfExtents].z - */ - fun volume(): Double { - return halfExtents.x * halfExtents.y * halfExtents.z - } - } + data class Box(val halfExtents: Vector3D) : ColliderShape() /** * Sphere shape with radius. */ - data class Sphere(val radius: Float) : ColliderShape() { - /** - * Returns the volume of the shape/sphere. - * - * In this case, volume is calculated as: (4/3) * π * [radius]^3 - */ - fun volume(): Double { - return (4.0 / 3.0) * PI * radius.toDouble().pow(3.0) - } - } + data class Sphere(val radius: Float) : ColliderShape() /** * Capsule shape along Y-axis. */ - data class Capsule(val halfHeight: Float, val radius: Float) : ColliderShape() { - /** - * Returns the volume of the shape/capsule. - * - * In this case, volume is calculated as: (4/3) * π * [radius]^3 + π * [radius]^2 * (2 * [halfHeight]) - */ - fun volume(): Double { - val sphereVolume = (4.0 / 3.0) * PI * radius.toDouble().pow(3.0) - val cylinderVolume = PI * radius.toDouble().pow(2.0) * (2.0 * halfHeight.toDouble()) - return sphereVolume + cylinderVolume - } - } + data class Capsule(val halfHeight: Float, val radius: Float) : ColliderShape() /** * Cylinder shape along Y-axis. */ - data class Cylinder(val halfHeight: Float, val radius: Float) : ColliderShape() { - /** - * Returns the volume of the shape/cylinder. - * - * In this case, volume is calculated as: π * [radius]^2 * (2 * [halfHeight]) - */ - fun volume(): Double { - return PI * radius.toDouble().pow(2.0) * (2.0 * halfHeight.toDouble()) - } - } - + data class Cylinder(val halfHeight: Float, val radius: Float) : ColliderShape() /** * Cone shape along Y-axis. */ - data class Cone(val halfHeight: Float, val radius: Float) : ColliderShape() { - /** - * Returns the volume of the shape/cone. - * - * In this case, volume is calculated as: (1/3) * π * [radius]^2 * (2 * [halfHeight]) - */ - fun volume(): Double { - return (1.0 / 3.0) * PI * radius.toDouble().pow(2.0) * (2.0 * halfHeight.toDouble()) - } - } + data class Cone(val halfHeight: Float, val radius: Float) : ColliderShape() } @@ -1,45 +1,47 @@ package com.dropbear.physics +import com.dropbear.ecs.Component import com.dropbear.EntityId -import com.dropbear.exceptionOnError -import com.dropbear.ffi.NativeEngine +import com.dropbear.ecs.ComponentType import com.dropbear.math.Vector3D class RigidBody( internal val index: Index, internal val entity: EntityId, - internal var native: NativeEngine, -) { +) : Component(entity, "RigidBody") { var rigidBodyMode: RigidBodyMode - get() = native.getRigidbodyMode(this) - set(value) = native.setRigidbodyMode(this, value) + get() = getRigidbodyMode(this) + set(value) = setRigidbodyMode(this, value) var gravityScale: Double - get() = native.getRigidbodyGravityScale(this) - set(value) = native.setRigidbodyGravityScale(this, value) + get() = getRigidbodyGravityScale(this) + set(value) = setRigidbodyGravityScale(this, value) var canSleep: Boolean - get() = native.getRigidbodyCanSleep(this) - set(value) = native.setRigidbodyCanSleep(this, value) + get() = getRigidbodyCanSleep(this) + set(value) = setRigidbodyCanSleep(this, value) var ccdEnabled: Boolean - get() = native.getRigidbodyCcdEnabled(this) - set(value) = native.setRigidbodyCcdEnabled(this, value) + get() = getRigidbodyCcdEnabled(this) + set(value) = setRigidbodyCcdEnabled(this, value) var linearVelocity: Vector3D - get() = native.getRigidbodyLinearVelocity(this) - set(value) = native.setRigidbodyLinearVelocity(this, value) + get() = getRigidbodyLinearVelocity(this) + set(value) = setRigidbodyLinearVelocity(this, value) var angularVelocity: Vector3D - get() = native.getRigidbodyAngularVelocity(this) - set(value) = native.setRigidbodyAngularVelocity(this, value) + get() = getRigidbodyAngularVelocity(this) + set(value) = setRigidbodyAngularVelocity(this, value) var linearDamping: Double - get() = native.getRigidbodyLinearDamping(this) - set(value) = native.setRigidbodyLinearDamping(this, value) + get() = getRigidbodyLinearDamping(this) + set(value) = setRigidbodyLinearDamping(this, value) var angularDamping: Double - get() = native.getRigidbodyAngularDamping(this) - set(value) = native.setRigidbodyAngularDamping(this, value) + get() = getRigidbodyAngularDamping(this) + set(value) = setRigidbodyAngularDamping(this, value) var lockTranslation: AxisLock - get() = native.getRigidbodyLockTranslation(this) - set(value) = native.setRigidbodyLockTranslation(this, value) + get() = getRigidbodyLockTranslation(this) + set(value) = setRigidbodyLockTranslation(this, value) var lockRotation: AxisLock - get() = native.getRigidbodyLockRotation(this) - set(value) = native.setRigidbodyLockRotation(this, value) + get() = getRigidbodyLockRotation(this) + set(value) = setRigidbodyLockRotation(this, value) + var childColliders: List<EntityId> + get() = getRigidbodyChildren(this) + set(value) = setRigidbodyChildren(this, value) /** * Applies an instant force. @@ -56,13 +58,9 @@ class RigidBody( * Typically used for jumping or explosions. */ fun applyImpulse(x: Double, y: Double, z: Double) { - val native = native ?: if (exceptionOnError) { - throw IllegalStateException("Native engine is not initialised") - } else { - return - } - return native.applyImpulse(index, x, y, z) + return applyImpulse(index, x, y, z) } + /** * Applies an instant torque/rotational impulse. * @@ -78,39 +76,40 @@ class RigidBody( * Typically used for spinning objects. */ fun applyTorqueImpulse(x: Double, y: Double, z: Double) { - val native = native ?: if (exceptionOnError) { - throw IllegalStateException("Native engine is not initialised") - } else { - return - } - return native.applyTorqueImpulse(index, x, y, z) + return applyTorqueImpulse(index, x, y, z) } - /** - * Pushes your changes to the [RigidBody] back to the physics engine. - */ - fun setRigidbody() { - val native = native ?: if (exceptionOnError) { - throw IllegalStateException("Native engine is not initialised") - } else { - return + companion object : ComponentType<RigidBody> { + override fun get(entityId: EntityId): RigidBody? { + val index = rigidBodyExistsForEntity(entityId) + return if (index != null) RigidBody(index, entityId) else null } - - native.setRigidbody(this) } +} - /** - * Fetches all child [Collider] under this [RigidBody]. - * - * Returns `null` if there is no component such as `ColliderGroup` attached to the - * entity, or an [emptyList] if there are no child colliders. - */ - fun getChildColliders(): List<Collider>? { - val native = native ?: if (exceptionOnError) { - throw IllegalStateException("Native engine is not initialised") - } else { - return null - } - return native.getChildColliders(index) - } -} +expect fun RigidBody.getRigidbodyMode(rigidBody: RigidBody): RigidBodyMode +expect fun RigidBody.setRigidbodyMode(rigidBody: RigidBody, mode: RigidBodyMode) +expect fun RigidBody.getRigidbodyGravityScale(rigidBody: RigidBody): Double +expect fun RigidBody.setRigidbodyGravityScale(rigidBody: RigidBody, gravityScale: Double) +expect fun RigidBody.getRigidbodyCanSleep(rigidBody: RigidBody): Boolean +expect fun RigidBody.setRigidbodyCanSleep(rigidBody: RigidBody, canSleep: Boolean) +expect fun RigidBody.getRigidbodyCcdEnabled(rigidBody: RigidBody): Boolean +expect fun RigidBody.setRigidbodyCcdEnabled(rigidBody: RigidBody, ccdEnabled: Boolean) +expect fun RigidBody.getRigidbodyLinearVelocity(rigidBody: RigidBody): Vector3D +expect fun RigidBody.setRigidbodyLinearVelocity(rigidBody: RigidBody, linearVelocity: Vector3D) +expect fun RigidBody.getRigidbodyAngularVelocity(rigidBody: RigidBody): Vector3D +expect fun RigidBody.setRigidbodyAngularVelocity(rigidBody: RigidBody, angularVelocity: Vector3D) +expect fun RigidBody.getRigidbodyLinearDamping(rigidBody: RigidBody): Double +expect fun RigidBody.setRigidbodyLinearDamping(rigidBody: RigidBody, linearDamping: Double) +expect fun RigidBody.getRigidbodyAngularDamping(rigidBody: RigidBody): Double +expect fun RigidBody.setRigidbodyAngularDamping(rigidBody: RigidBody, angularDamping: Double) +expect fun RigidBody.getRigidbodyLockTranslation(rigidBody: RigidBody): AxisLock +expect fun RigidBody.setRigidbodyLockTranslation(rigidBody: RigidBody, lockTranslation: AxisLock) +expect fun RigidBody.getRigidbodyLockRotation(rigidBody: RigidBody): AxisLock +expect fun RigidBody.setRigidbodyLockRotation(rigidBody: RigidBody, lockRotation: AxisLock) +expect fun RigidBody.getRigidbodyChildren(rigidBody: RigidBody): List<EntityId> +expect fun RigidBody.setRigidbodyChildren(rigidBody: RigidBody, children: List<EntityId>) +expect fun RigidBody.applyImpulse(index: Index, x: Double, y: Double, z: Double) +expect fun RigidBody.applyTorqueImpulse(index: Index, x: Double, y: Double, z: Double) + +expect fun rigidBodyExistsForEntity(entityId: EntityId): Index? @@ -8,7 +8,7 @@ import com.dropbear.ffi.NativeEngine /** * A handle that allows you to check the state of an async scene load. */ -class SceneLoadHandle(val id: Long, val sceneName: String, val native: NativeEngine) { +class SceneLoadHandle(val id: Long, val sceneName: String) { /** * Switches the scene to the requested scene. * @@ -19,18 +19,18 @@ class SceneLoadHandle(val id: Long, val sceneName: String, val native: NativeEng * is enabled or not. */ fun switchTo() { - native.switchToSceneAsync(this) + switchToSceneAsync() } /** * Returns the progress of scene load. */ fun progress(): Progress { - return native.getSceneLoadProgress(this) + return getSceneLoadProgress() } fun status(): SceneLoadStatus { - return native.getSceneLoadStatus(this) + return getSceneLoadStatus() } /** @@ -61,4 +61,8 @@ class SceneLoadHandle(val id: Long, val sceneName: String, val native: NativeEng fun raw(): Long { return id } -} +} + +expect fun SceneLoadHandle.switchToSceneAsync(): SceneLoadHandle +expect fun SceneLoadHandle.getSceneLoadProgress(): Progress +expect fun SceneLoadHandle.getSceneLoadStatus(): SceneLoadStatus @@ -1,8 +1,6 @@ package com.dropbear.scene -import com.dropbear.ffi.NativeEngine - -class SceneManager(val native: NativeEngine) { +class SceneManager() { /** * Loads the resources of a scene asynchronously. * @@ -11,20 +9,20 @@ class SceneManager(val native: NativeEngine) { * and check its status. */ fun loadSceneAsync(sceneName: String): SceneLoadHandle? { - return native.loadSceneAsync(sceneName) + return loadSceneAsyncNative(sceneName) } /** * Loads the resources of a scene asynchronously. * - * This function is an overload, which contains a `loading_scene` parameter. + * This function is an overload, which contains a `loadingScene` parameter. * This allows you to specify a scene to display while the resources are being loaded. * * It must be preloaded (through the scene settings menu in eucalyptus-editor). If not preloaded, it will - * block/freeze the main thread/window to load the `loading_scene` + * block/freeze the main thread/window to load the `loadingScene` */ - fun loadSceneAsync(sceneName: String, loading_scene: String): SceneLoadHandle? { - return native.loadSceneAsync(sceneName, loading_scene) + fun loadSceneAsync(sceneName: String, loadingScene: String): SceneLoadHandle? { + return loadSceneAsyncNative(sceneName, loadingScene) } /** @@ -35,7 +33,7 @@ class SceneManager(val native: NativeEngine) { * as 3D objects. Use [loadSceneAsync] instead. */ fun switchToSceneImmediate(sceneName: String) { - return native.switchToSceneImmediate(sceneName) + return switchToSceneImmediateNative(sceneName) } /** @@ -44,4 +42,8 @@ class SceneManager(val native: NativeEngine) { fun getCurrentScene(): SceneMetadata { TODO("Not implemented yet...") } -} +} + +expect fun SceneManager.loadSceneAsyncNative(sceneName: String): SceneLoadHandle? +expect fun SceneManager.loadSceneAsyncNative(sceneName: String, loading_scene: String): SceneLoadHandle? +expect fun SceneManager.switchToSceneImmediateNative(sceneName: String) @@ -1,7 +0,0 @@ -package com.dropbear.ui - -import com.dropbear.ffi.NativeEngine - -class UIManager(native: NativeEngine) { - -} @@ -1,16 +0,0 @@ -package com.dropbear; - -import java.lang.System; - -public class NativeEngineLoader { - private static boolean loaded = false; - - /// Ensures that the eucalyptus_core library is loaded before accessing - /// any of the JNI static functions. - public static void ensureLoaded() { - if (!loaded) { - System.loadLibrary("eucalyptus_core"); - loaded = true; - } - } -} @@ -1,11 +0,0 @@ -package com.dropbear.ffi; - -import com.dropbear.NativeEngineLoader; - -public class DropbearEngineNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native void quit(long graphicsHandle); -} @@ -1,26 +0,0 @@ -package com.dropbear.ffi; - -import com.dropbear.NativeEngineLoader; -import com.dropbear.input.Gamepad; - -public class InputStateNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - // input - public static native void printInputState(long inputHandle); - public static native boolean isKeyPressed(long inputHandle, int ordinal); - public static native float[] getMousePosition(long inputHandle); - public static native boolean isMouseButtonPressed(long inputHandle, int ordinal); - public static native float[] getMouseDelta(long inputHandle); - public static native boolean isCursorLocked(long inputHandle); - public static native void setCursorLocked(long inputHandle, long graphicsHandle, boolean locked); - public static native float[] getLastMousePos(long inputHandle); - public static native boolean isCursorHidden(long inputHandle); - public static native void setCursorHidden(long inputHandle, long graphicsHandle, boolean hidden); - - // gamepad stuff - public static native Gamepad[] getConnectedGamepads(long inputHandle); - public static native boolean isGamepadButtonPressed(long inputHandle, long gamepadId, int gamepadButtonOrdinal); -} @@ -1,20 +0,0 @@ -package com.dropbear.ffi; - -import com.dropbear.Camera; -import com.dropbear.EntityTransform; -import com.dropbear.NativeEngineLoader; -import com.dropbear.math.Transform; -import com.dropbear.scene.SceneLoadHandle; -import com.dropbear.utils.Progress; - -/** - * Describes all the functions that are available in - * the `eucalyptus_core` dynamic library. - */ -public class JNINative { - static { - NativeEngineLoader.ensureLoaded(); - } - public static native long getEntity(long worldHandle, String label); - public static native long getAsset(long assetRegistryHandle, String eucaURI); -} @@ -1,16 +0,0 @@ -package com.dropbear.ffi; - -import com.dropbear.NativeEngineLoader; -import com.dropbear.physics.Collider; -import com.dropbear.physics.RigidBody; - -public class PhysicsNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native void setPhysicsEnabled(long worldHandle, long physicsEngineHandle, long entityId, boolean enabled); - public static native boolean isPhysicsEnabled(long worldHandle, long physicsEngineHandle, long entityId); - public static native RigidBody getRigidBody(long worldHandle, long physicsEngineHandle, long entityId); - public static native Collider[] getAllColliders(long worldHandle, long physicsEngineHandle, long entityId); -} @@ -1,19 +0,0 @@ -package com.dropbear.ffi; - -import com.dropbear.NativeEngineLoader; -import com.dropbear.scene.SceneLoadHandle; -import com.dropbear.scene.SceneLoadStatus; -import com.dropbear.utils.Progress; - -public class SceneNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native SceneLoadHandle loadSceneAsync(long commandBufferHandle, long sceneLoader, String sceneName, NativeEngine engine); - public static native SceneLoadHandle loadSceneAsync(long commandBufferHandle, long sceneLoader, String sceneName, String loadingScene, NativeEngine engine); - public static native void switchToSceneAsync(long commandBufferHandle, SceneLoadHandle handle); - public static native void switchToSceneImmediate(long commandBufferHandle, String sceneName); - public static native Progress getSceneLoadProgress(long sceneLoader, SceneLoadHandle handle); - public static native SceneLoadStatus getSceneLoadStatus(long sceneLoader, SceneLoadHandle handle); -} @@ -1,14 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.Camera; -import com.dropbear.NativeEngineLoader; - -public class CameraNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native Camera getCamera(long worldHandle, String label); - public static native Camera getAttachedCamera(long worldHandle, long entityHandle); - public static native void setCamera(long worldHandle, Camera camera); -} @@ -1,11 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.physics.Collider; - -public class ColliderNative { - static { - com.dropbear.NativeEngineLoader.ensureLoaded(); - } - - public static native void setCollider(long worldHandle, long physicsEngineHandle, Collider collider); -} @@ -1,25 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.NativeEngineLoader; - -public class CustomPropertiesNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - // properties - public static native String getStringProperty(long worldHandle, long entityHandle, String label); - public static native int getIntProperty(long worldHandle, long entityHandle, String label); - public static native long getLongProperty(long worldHandle, long entityHandle, String label); - public static native double getFloatProperty(long worldHandle, long entityHandle, String label); - public static native boolean getBoolProperty(long worldHandle, long entityHandle, String label); - public static native float[] getVec3Property(long worldHandle, long entityHandle, String label); - - public static native void setStringProperty(long worldHandle, long entityHandle, String label, String value); - public static native void setIntProperty(long worldHandle, long entityHandle, String label, int value); - public static native void setLongProperty(long worldHandle, long entityHandle, String label, long value); - public static native void setFloatProperty(long worldHandle, long entityHandle, String label, double value); - public static native void setBoolProperty(long worldHandle, long entityHandle, String label, boolean value); - public static native void setVec3Property(long worldHandle, long entityHandle, String label, float[] value); - -} @@ -1,15 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.EntityTransform; -import com.dropbear.NativeEngineLoader; -import com.dropbear.math.Transform; - -public class EntityTransformNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native EntityTransform getTransform(long handle, long entityHandle); - public static native Transform propagateTransform(long worldHandle, long id); - public static native void setTransform(long worldHandle, long id, EntityTransform transform); -} @@ -1,13 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.NativeEngineLoader; - -public class HierarchyNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native long[] getChildren(long worldHandle, long entityId); - public static native long getChildByLabel(long worldHandle, long entityId, String label); - public static native long getParent(long worldHandle, long entityId); -} @@ -1,11 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.NativeEngineLoader; - -public class LabelNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - public static native String getEntityLabel(long worldHandle, long entityHandle); -} @@ -1,25 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.NativeEngineLoader; - -public class MeshRendererNative { - static { - NativeEngineLoader.ensureLoaded(); - } - - // model - public static native long getModel(long worldHandle, long entityHandle); - public static native void setModel(long worldHandle, long assetHandle, long entityHandle, long modelHandle); - public static native boolean isModelHandle(long assetRegistryHandle, long handle); - public static native boolean isUsingModel(long worldHandle, long entityHandle, long modelHandle); - - // texture - public static native long getTexture(long worldHandle, long assetHandle, long entityHandle, String name); - public static native String getTextureName(long assetHandle, long textureHandle); - public static native void setTexture(long worldHandle, long assetRegistryHandle, long entityHandle, - String oldMaterialName, long textureHandle); - public static native boolean isTextureHandle(long assetRegistryHandle, long handle); - public static native boolean isUsingTexture(long worldHandle, long entityHandle, long textureHandle); - - public static native String[] getAllTextures(long worldHandle, long entityHandle); -} @@ -1,17 +0,0 @@ -package com.dropbear.ffi.components; - -import com.dropbear.physics.Collider; -import com.dropbear.physics.Index; -import com.dropbear.physics.RigidBody; - -public class RigidBodyNative { - static { - com.dropbear.NativeEngineLoader.ensureLoaded(); - } - - public static native void applyImpulse(long physicsEngineHandle, Index rigidBodyId, double x, double y, double z); - public static native void applyTorqueImpulse(long physicsEngineHandle, Index rigidBodyId, double x, double y, double z); - - public static native void setRigidBody(long worldHandle, long physicsEngineHandle, RigidBody rigidBody); - public static native Collider[] getChildColliders(long worldHandle, long physicsEngineHandle, Index rigidBodyId); -} @@ -0,0 +1,81 @@ +package com.dropbear + +import com.dropbear.math.Vector3D + +actual fun Camera.getCameraEye(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraEye(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraTarget(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraTarget(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraUp(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraUp(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraAspect(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.getCameraFovY(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraFovY(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraZNear(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraZNear(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraZFar(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraZFar(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraYaw(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraYaw(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraPitch(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraPitch(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraSpeed(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraSpeed(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraSensitivity(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraSensitivity(entity: EntityId, value: Double) { +} + +actual fun cameraExistsForEntity(entity: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,93 @@ +package com.dropbear + +actual fun CustomProperties.getStringProperty( + entityHandle: Long, + label: String +): String? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getIntProperty(entityHandle: Long, label: String): Int? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getLongProperty( + entityHandle: Long, + label: String +): Long? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getDoubleProperty( + entityHandle: Long, + label: String +): Double? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getFloatProperty( + entityHandle: Long, + label: String +): Float? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getBoolProperty( + entityHandle: Long, + label: String +): Boolean? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getVec3Property( + entityHandle: Long, + label: String +): FloatArray? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.setStringProperty( + entityHandle: Long, + label: String, + value: String +) { +} + +actual fun CustomProperties.setIntProperty( + entityHandle: Long, + label: String, + value: Int +) { +} + +actual fun CustomProperties.setLongProperty( + entityHandle: Long, + label: String, + value: Long +) { +} + +actual fun CustomProperties.setFloatProperty( + entityHandle: Long, + label: String, + value: Double +) { +} + +actual fun CustomProperties.setBoolProperty( + entityHandle: Long, + label: String, + value: Boolean +) { +} + +actual fun CustomProperties.setVec3Property( + entityHandle: Long, + label: String, + value: FloatArray +) { +} + +actual fun customPropertiesExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,16 @@ +package com.dropbear + +actual fun getEntity(label: String): Long? { + TODO("Not yet implemented") +} + +actual fun getCamera(label: String): Camera? { + TODO("Not yet implemented") +} + +actual fun getAsset(eucaURI: String): Long? { + TODO("Not yet implemented") +} + +actual fun quit() { +} @@ -0,0 +1,12 @@ +package com.dropbear; + +/// Interface for dynamic library loading, allowing for custom components not within the dropbear component +/// library. +public interface DynamicLibraryLoader { + /// Ensures that the library is loaded before accessing + /// any of the JNI static functions. + void ensureLoaded(); + + /// Forces the library to have a loaded boolean variable. + boolean isLoaded(); +} @@ -0,0 +1,20 @@ +package com.dropbear + +actual fun EntityRef.getEntityLabel(entity: EntityId): String? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getChildren(entityId: EntityId): Array<EntityRef>? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getChildByLabel( + entityId: EntityId, + label: String +): EntityRef? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getParent(entityId: EntityId): EntityRef? { + TODO("Not yet implemented") +} @@ -0,0 +1,31 @@ +package com.dropbear + +import com.dropbear.math.Transform + +actual fun EntityTransform.getLocalTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun EntityTransform.setLocalTransform( + entityId: EntityId, + transform: Transform +) { +} + +actual fun EntityTransform.getWorldTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun EntityTransform.setWorldTransform( + entityId: EntityId, + transform: Transform +) { +} + +actual fun EntityTransform.propagateTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun entityTransformExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,20 @@ +package com.dropbear; + +import java.lang.System; + +public class EucalyptusCoreLoader implements DynamicLibraryLoader { + private static boolean loaded = false; + + @Override + public void ensureLoaded() { + if (!loaded) { + System.loadLibrary("eucalyptus_core"); + loaded = true; + } + } + + @Override + public boolean isLoaded() { + return loaded; + } +} @@ -0,0 +1,37 @@ +package com.dropbear + +import com.dropbear.asset.ModelHandle +import com.dropbear.asset.TextureHandle + +actual fun MeshRenderer.getModel(id: EntityId): ModelHandle? { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setModel(id: EntityId, model: ModelHandle?) { +} + +actual fun MeshRenderer.getAllTextureIds(id: EntityId): List<TextureHandle>? { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.getMaterialNames(id: EntityId): List<String> { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setMaterialNames(id: EntityId, names: Array<String>) { +} + +actual fun MeshRenderer.getTexture(id: EntityId, materialName: String): Long { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setTextureOverride( + id: EntityId, + materialName: String, + textureHandle: Long +) { +} + +actual fun meshRendererExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,9 @@ +package com.dropbear.asset + +actual fun AssetHandle.asTextureHandle(): TextureHandle? { + TODO("Not yet implemented") +} + +actual fun isModelHandle(id: Long): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,5 @@ +package com.dropbear.asset + +actual fun TextureHandle.getTextureName(id: Long): String? { + TODO("Not yet implemented") +} @@ -1,11 +0,0 @@ -package com.dropbear.ffi - -import com.dropbear.DropbearEngine - -actual fun getEntity(label: String): Long? { - TODO("Not yet implemented") -} -actual fun getAsset(eucaURI: String): Long? { - DropbearEngine.native.assetHandle - TODO("Not yet implemented") -} @@ -1,37 +1,6 @@ package com.dropbear.ffi -import com.dropbear.Camera -import com.dropbear.EntityId -import com.dropbear.EntityRef -import com.dropbear.EntityTransform -import com.dropbear.asset.TextureHandle -import com.dropbear.exception.DropbearNativeException -import com.dropbear.exceptionOnError -import com.dropbear.ffi.JNINative.* -import com.dropbear.ffi.InputStateNative.* -import com.dropbear.ffi.DropbearEngineNative.* -import com.dropbear.ffi.components.HierarchyNative.* -import com.dropbear.ffi.components.CameraNative.* -import com.dropbear.ffi.components.ColliderNative -import com.dropbear.ffi.components.LabelNative.* -import com.dropbear.ffi.components.MeshRendererNative.* -import com.dropbear.ffi.components.EntityTransformNative.* -import com.dropbear.ffi.components.CustomPropertiesNative.* -import com.dropbear.ffi.components.RigidBodyNative -import com.dropbear.input.Gamepad -import com.dropbear.input.GamepadButton -import com.dropbear.input.KeyCode -import com.dropbear.input.MouseButton -import com.dropbear.input.MouseButtonCodes import com.dropbear.logging.Logger -import com.dropbear.math.Transform -import com.dropbear.math.Vector2D -import com.dropbear.physics.Collider -import com.dropbear.physics.Index -import com.dropbear.physics.RigidBody -import com.dropbear.scene.SceneLoadHandle -import com.dropbear.scene.SceneLoadStatus -import com.dropbear.utils.Progress actual class NativeEngine { internal var worldHandle: Long = 0L @@ -75,409 +44,4 @@ actual class NativeEngine { return } } - - actual fun getEntityLabel(entityHandle: Long) : String? { - val result = getEntityLabel(worldHandle, entityHandle) ?: if (exceptionOnError) { - throw DropbearNativeException("Unable to get entity label for entity $entityHandle") - } else { - return null - } - return result - } - - actual fun getEntity(label: String): Long? { - val result = getEntity(worldHandle, label) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get entity: returned -1") - } else { - null - } - } else if (result == 0L) { - null - } else { - result - } - } - - - actual fun getTransform(entityId: EntityId): EntityTransform? { - return getTransform(worldHandle, entityId.id) - } - - actual fun propagateTransform(entityId: EntityId): Transform? { - return propagateTransform(worldHandle, entityId.id) - } - - actual fun setTransform(entityId: EntityId, transform: EntityTransform) { - return setTransform(worldHandle, entityId.id, transform) - } - - actual fun printInputState() { - return printInputState(inputHandle) - } - - actual fun isKeyPressed(key: KeyCode): Boolean { - return isKeyPressed(inputHandle, key.ordinal) - } - - actual fun getMousePosition(): Vector2D? { - val result = getMousePosition(inputHandle); - return Vector2D(result[0].toDouble(), result[1].toDouble()) - } - - actual fun isMouseButtonPressed(button: MouseButton): Boolean { - val buttonCode: Int = when (button) { - MouseButton.Left -> MouseButtonCodes.LEFT - MouseButton.Right -> MouseButtonCodes.RIGHT - MouseButton.Middle -> MouseButtonCodes.MIDDLE - MouseButton.Back -> MouseButtonCodes.BACK - MouseButton.Forward -> MouseButtonCodes.FORWARD - is MouseButton.Other -> button.value - } - - return isMouseButtonPressed(inputHandle, buttonCode) - } - - actual fun getConnectedGamepads(): List<Gamepad> { - val result = getConnectedGamepads(inputHandle) - return result.toList() - } - - actual fun isGamepadButtonPressed(id: Long, button: GamepadButton): Boolean { - return isGamepadButtonPressed(inputHandle, id, button.ordinal) - } - - actual fun getMouseDelta(): Vector2D? { - val result = getMouseDelta(inputHandle); - return Vector2D(result[0].toDouble(), result[1].toDouble()) - } - - actual fun isCursorLocked(): Boolean { - return isCursorLocked(inputHandle) - } - - actual fun setCursorLocked(locked: Boolean) { - setCursorLocked(inputHandle, commandBufferHandle, locked) - } - - actual fun getLastMousePos(): Vector2D? { - val result = getLastMousePos(inputHandle); - return Vector2D(result[0].toDouble(), result[1].toDouble()) - } - - actual fun getStringProperty(entityHandle: Long, label: String): String? { - return getStringProperty(worldHandle, entityHandle, label) - } - - actual fun getIntProperty(entityHandle: Long, label: String): Int? { - val result = getIntProperty(worldHandle, entityHandle, label) - return if (result == 650911) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get integer property for entity $label") - } else { - null - } - } else { - result - } - } - - actual fun getLongProperty(entityHandle: Long, label: String): Long? { - val result = getLongProperty(worldHandle, entityHandle, label) - return if (result == 6509112938) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get long property for entity $label") - } else { - null - } - } else { - result - } - } - - actual fun getFloatProperty(entityHandle: Long, label: String): Float? { - val result = getFloatProperty(worldHandle, entityHandle, label) - return if (result.isNaN()) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get float property for entity $label") - } else { - null - } - } else { - result.toFloat() - } - } - - actual fun getDoubleProperty(entityHandle: Long, label: String): Double? { - val result = getFloatProperty(worldHandle, entityHandle, label) - return if (result.isNaN()) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get double (float) property") - } else { - null - } - } else { - result - } - } - - actual fun getBoolProperty(entityHandle: Long, label: String): Boolean? { - return getBoolProperty(worldHandle, entityHandle, label) - } - - actual fun getVec3Property(entityHandle: Long, label: String): FloatArray? { - return getVec3Property(worldHandle, entityHandle, label) - } - - actual fun setStringProperty(entityHandle: Long, label: String, value: String) { - setStringProperty(worldHandle, entityHandle, label, value) - } - - actual fun setIntProperty(entityHandle: Long, label: String, value: Int) { - setIntProperty(worldHandle, entityHandle, label, value) - } - - actual fun setLongProperty(entityHandle: Long, label: String, value: Long) { - setLongProperty(worldHandle, entityHandle, label, value) - } - - actual fun setFloatProperty(entityHandle: Long, label: String, value: Double) { - setFloatProperty(worldHandle, entityHandle, label, value) - } - - actual fun setBoolProperty(entityHandle: Long, label: String, value: Boolean) { - setBoolProperty(worldHandle, entityHandle, label, value) - } - - actual fun setVec3Property(entityHandle: Long, label: String, value: FloatArray) { - setVec3Property(worldHandle, entityHandle, label, value) - } - - actual fun getCamera(label: String): Camera? { - return getCamera(worldHandle, label) - } - - actual fun getAttachedCamera(entityId: EntityId): Camera? { - return getAttachedCamera(worldHandle, entityId.id) - } - - actual fun setCamera(camera: Camera) { - setCamera(worldHandle, camera) - } - - actual fun isCursorHidden(): Boolean { - return isCursorHidden(inputHandle) - } - - actual fun setCursorHidden(hidden: Boolean) { - setCursorHidden(inputHandle, commandBufferHandle, hidden) - } - - actual fun getModel(entityHandle: Long): Long? { - val result = getModel(worldHandle, entityHandle) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get model for entity $entityHandle") - } else { - null - } - } else if (result == 0L) { - null - } else { - result - } - } - - actual fun setModel(entityHandle: Long, modelHandle: Long) { - setModel(worldHandle, assetHandle, entityHandle, modelHandle) - } - - actual fun getTexture(entityHandle: Long, name: String): Long? { - val result = getTexture(worldHandle, assetHandle, entityHandle, name) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get texture for entity $entityHandle") - } else { - null - } - } else if (result == 0L) { - null - } else { - result - } - } - - actual fun setTextureOverride(entityHandle: Long, oldMaterialName: String, newTextureHandle: TextureHandle) { - return setTexture( - worldHandle, - assetHandle, - entityHandle, - oldMaterialName, - newTextureHandle.raw() - ) - } - - actual fun getTextureName(textureHandle: Long): String? { - return getTextureName(assetHandle, textureHandle) - } - - actual fun isUsingModel(entityHandle: Long, modelHandle: Long): Boolean { - return isUsingModel(worldHandle, entityHandle, modelHandle) - } - - actual fun isUsingTexture(entityHandle: Long, textureHandle: Long): Boolean { - return isUsingTexture(worldHandle, entityHandle, textureHandle) - } - - actual fun getAsset(eucaURI: String): Long? { - val result = getAsset(assetHandle, eucaURI) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get asset for URI $eucaURI") - } else { - null - } - } else if (result == 0L) { - // no asset found - null - } else { - result - } - } - - actual fun isModelHandle(id: Long): Boolean { - return isModelHandle(assetHandle, id) - } - - actual fun isTextureHandle(id: Long): Boolean { - return isTextureHandle(assetHandle, id) - } - - actual fun getAllTextures(entityHandle: Long): Array<String> { - return getAllTextures(worldHandle, entityHandle) ?: emptyArray() - } - - actual fun getChildren(entityId: EntityId): Array<EntityRef>? { - val result = getChildren(worldHandle, entityId.id) - // i shouldn't expect it to return null unless an error, otherwise it must - // return an empty array - if (result == null) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to query for all children for entity ${entityId.id}") - } else { - return null - } - } else { - val entityRefs = mutableListOf<EntityRef>() - result.forEach { e -> - entityRefs.add(EntityRef(EntityId(e))) - } - return entityRefs.toTypedArray() // must be an array so it cannot be mutated - } - } - - actual fun getChildByLabel(entityId: EntityId, label: String): EntityRef? { - val result = getChildByLabel(worldHandle, entityId.id, label) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get child by label $entityId $label") - } else { - null - } - } else if (result == -2L) { - null - } else { - EntityRef(EntityId(result)) - } - } - - actual fun getParent(entityId: EntityId): EntityRef? { - val result = getParent(worldHandle, entityId.id) - return if (result == -1L) { - if (exceptionOnError) { - throw DropbearNativeException("Unable to get parent of entity $entityId") - } else { - null - } - } else if (result == -2L) { - null - } else { - EntityRef(EntityId(result)) - } - } - - actual fun quit() { - quit(commandBufferHandle) - } - - actual fun switchToSceneImmediate(sceneName: String) { - SceneNative.switchToSceneImmediate(commandBufferHandle, sceneName) - } - - actual fun loadSceneAsync(sceneName: String): SceneLoadHandle? { - return SceneNative.loadSceneAsync(commandBufferHandle, sceneLoaderHandle, sceneName, this) - } - - actual fun loadSceneAsync(sceneName: String, loadingScene: String): SceneLoadHandle? { - return SceneNative.loadSceneAsync(commandBufferHandle, sceneLoaderHandle, sceneName, loadingScene, this) - } - - actual fun switchToSceneAsync(sceneLoadHandle: SceneLoadHandle) { - SceneNative.switchToSceneAsync(commandBufferHandle, sceneLoadHandle) // will throw exception from JNI interface - } - - actual fun getSceneLoadProgress(sceneLoadHandle: SceneLoadHandle): Progress { - return SceneNative.getSceneLoadProgress(sceneLoaderHandle, sceneLoadHandle) - } - - actual fun getSceneLoadStatus(sceneLoadHandle: SceneLoadHandle): SceneLoadStatus { - return SceneNative.getSceneLoadStatus(sceneLoaderHandle, sceneLoadHandle) - } - - actual fun setPhysicsEnabled(entityId: Long, enabled: Boolean) { - return PhysicsNative.setPhysicsEnabled(worldHandle, physicsEngineHandle, entityId, enabled) - } - - actual fun isPhysicsEnabled(entityId: Long): Boolean { - return PhysicsNative.isPhysicsEnabled(worldHandle, physicsEngineHandle, entityId) - } - - actual fun getRigidBody(entityId: Long): RigidBody? { - val result = PhysicsNative.getRigidBody(worldHandle, physicsEngineHandle, entityId) - result.native = this@NativeEngine - return result - } - - actual fun getAllColliders(entityId: Long): List<Collider> { - val result = PhysicsNative.getAllColliders(worldHandle, physicsEngineHandle, entityId) - result.forEach { - it.native = this@NativeEngine - } - return result.toList() - } - - actual fun applyImpulse(index: Index, x: Double, y: Double, z: Double) { - return RigidBodyNative.applyImpulse(physicsEngineHandle, index, x, y, z) - } - - actual fun applyTorqueImpulse(index: Index, x: Double, y: Double, z: Double) { - return RigidBodyNative.applyTorqueImpulse(physicsEngineHandle, index, x, y, z) - } - - actual fun setRigidbody(rigidBody: RigidBody) { - return RigidBodyNative.setRigidBody(worldHandle, physicsEngineHandle, rigidBody) - } - - actual fun getChildColliders(index: Index): List<Collider> { - val result = RigidBodyNative.getChildColliders(worldHandle, physicsEngineHandle, index) - result.forEach { - it.native = this@NativeEngine - } - return result.toList() - } - - actual fun setCollider(collider: Collider) { - return ColliderNative.setCollider(worldHandle, physicsEngineHandle, collider) - } -} +} @@ -1,7 +1,7 @@ package com.dropbear.host import com.dropbear.DropbearEngine -import com.dropbear.System +import com.dropbear.ecs.System import com.dropbear.logging.LogLevel import com.dropbear.logging.LogWriter import com.dropbear.logging.Logger @@ -0,0 +1,8 @@ +package com.dropbear.input + +actual fun Gamepad.isGamepadButtonPressed( + id: Long, + button: GamepadButton +): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,46 @@ +package com.dropbear.input + +import com.dropbear.math.Vector2D + +actual class InputState actual constructor() { + actual fun printInputState() { + } + + actual fun isKeyPressed(key: KeyCode): Boolean { + TODO("Not yet implemented") + } + + actual fun getMousePosition(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isMouseButtonPressed(button: MouseButton): Boolean { + TODO("Not yet implemented") + } + + actual fun getMouseDelta(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isCursorLocked(): Boolean { + TODO("Not yet implemented") + } + + actual fun setCursorLocked(locked: Boolean) { + } + + actual fun getLastMousePos(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isCursorHidden(): Boolean { + TODO("Not yet implemented") + } + + actual fun setCursorHidden(hidden: Boolean) { + } + + actual fun getConnectedGamepads(): List<Gamepad> { + TODO("Not yet implemented") + } +} @@ -0,0 +1,80 @@ +package com.dropbear.physics + +import com.dropbear.math.Vector3D + +actual fun Collider.getColliderShape(collider: Collider): ColliderShape { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderShape( + collider: Collider, + shape: ColliderShape +) { +} + +actual fun Collider.setColliderDensity( + collider: Collider, + density: Double +) { +} + +actual fun Collider.getColliderFriction(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderFriction( + collider: Collider, + friction: Double +) { +} + +actual fun Collider.getColliderRestitution(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderRestitution( + collider: Collider, + restitution: Double +) { +} + +actual fun Collider.getColliderIsSensor(collider: Collider): Boolean { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderIsSensor( + collider: Collider, + isSensor: Boolean +) { +} + +actual fun Collider.getColliderTranslation(collider: Collider): Vector3D { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderTranslation( + collider: Collider, + translation: Vector3D +) { +} + +actual fun Collider.setColliderRotation( + collider: Collider, + rotation: Vector3D +) { +} + +actual fun Collider.getColliderRotation(collider: Collider): Vector3D { + TODO("Not yet implemented") +} + +actual fun Collider.getColliderMass(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderMass(collider: Collider, mass: Double) { +} + +actual fun Collider.getColliderDensity(collider: Collider): Double { + TODO("Not yet implemented") +} @@ -0,0 +1,11 @@ +package com.dropbear.physics + +import com.dropbear.EntityId + +actual fun ColliderGroup.getColliderGroupColliders(colliderGroup: ColliderGroup): List<Collider> { + TODO("Not yet implemented") +} + +actual fun colliderGroupExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,135 @@ +package com.dropbear.physics + +import com.dropbear.EntityId +import com.dropbear.math.Vector3D + +actual fun RigidBody.getRigidbodyMode(rigidBody: RigidBody): RigidBodyMode { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyMode( + rigidBody: RigidBody, + mode: RigidBodyMode +) { +} + +actual fun RigidBody.getRigidbodyGravityScale(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyGravityScale( + rigidBody: RigidBody, + gravityScale: Double +) { +} + +actual fun RigidBody.getRigidbodyCanSleep(rigidBody: RigidBody): Boolean { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyCanSleep( + rigidBody: RigidBody, + canSleep: Boolean +) { +} + +actual fun RigidBody.getRigidbodyCcdEnabled(rigidBody: RigidBody): Boolean { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyCcdEnabled( + rigidBody: RigidBody, + ccdEnabled: Boolean +) { +} + +actual fun RigidBody.getRigidbodyLinearVelocity(rigidBody: RigidBody): Vector3D { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLinearVelocity( + rigidBody: RigidBody, + linearVelocity: Vector3D +) { +} + +actual fun RigidBody.getRigidbodyAngularVelocity(rigidBody: RigidBody): Vector3D { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyAngularVelocity( + rigidBody: RigidBody, + angularVelocity: Vector3D +) { +} + +actual fun RigidBody.getRigidbodyLinearDamping(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.getRigidbodyAngularDamping(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyAngularDamping( + rigidBody: RigidBody, + angularDamping: Double +) { +} + +actual fun RigidBody.getRigidbodyLockTranslation(rigidBody: RigidBody): AxisLock { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLockTranslation( + rigidBody: RigidBody, + lockTranslation: AxisLock +) { +} + +actual fun RigidBody.getRigidbodyLockRotation(rigidBody: RigidBody): AxisLock { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLockRotation( + rigidBody: RigidBody, + lockRotation: AxisLock +) { +} + +actual fun RigidBody.getRigidbodyChildren(rigidBody: RigidBody): List<EntityId> { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyChildren( + rigidBody: RigidBody, + children: List<EntityId> +) { +} + +actual fun RigidBody.applyImpulse( + index: Index, + x: Double, + y: Double, + z: Double +) { +} + +actual fun RigidBody.applyTorqueImpulse( + index: Index, + x: Double, + y: Double, + z: Double +) { +} + +actual fun RigidBody. + setRigidbodyLinearDamping( + rigidBody: RigidBody, + linearDamping: Double +) { +} + +actual fun rigidBodyExistsForEntity(entityId: EntityId): Index? { + TODO("Not yet implemented") +} @@ -0,0 +1,15 @@ +package com.dropbear.scene + +import com.dropbear.utils.Progress + +actual fun SceneLoadHandle.switchToSceneAsync(): SceneLoadHandle { + TODO("Not yet implemented") +} + +actual fun SceneLoadHandle.getSceneLoadProgress(): Progress { + TODO("Not yet implemented") +} + +actual fun SceneLoadHandle.getSceneLoadStatus(): SceneLoadStatus { + TODO("Not yet implemented") +} @@ -0,0 +1,15 @@ +package com.dropbear.scene + +actual fun SceneManager.loadSceneAsyncNative(sceneName: String): SceneLoadHandle? { + TODO("Not yet implemented") +} + +actual fun SceneManager.loadSceneAsyncNative( + sceneName: String, + loading_scene: String +): SceneLoadHandle? { + TODO("Not yet implemented") +} + +actual fun SceneManager.switchToSceneImmediateNative(sceneName: String) { +} @@ -0,0 +1,81 @@ +package com.dropbear + +import com.dropbear.math.Vector3D + +actual fun Camera.getCameraEye(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraEye(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraTarget(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraTarget(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraUp(entity: EntityId): Vector3D { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraUp(entity: EntityId, value: Vector3D) { +} + +actual fun Camera.getCameraAspect(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.getCameraFovY(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraFovY(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraZNear(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraZNear(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraZFar(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraZFar(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraYaw(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.getCameraPitch(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraYaw(entity: EntityId, value: Double) { +} + +actual fun Camera.setCameraPitch(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraSpeed(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraSpeed(entity: EntityId, value: Double) { +} + +actual fun Camera.getCameraSensitivity(entity: EntityId): Double { + TODO("Not yet implemented") +} + +actual fun Camera.setCameraSensitivity(entity: EntityId, value: Double) { +} + +actual fun cameraExistsForEntity(entity: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,93 @@ +package com.dropbear + +actual fun CustomProperties.getStringProperty( + entityHandle: Long, + label: String +): String? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getIntProperty(entityHandle: Long, label: String): Int? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getLongProperty( + entityHandle: Long, + label: String +): Long? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getDoubleProperty( + entityHandle: Long, + label: String +): Double? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getFloatProperty( + entityHandle: Long, + label: String +): Float? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getBoolProperty( + entityHandle: Long, + label: String +): Boolean? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.getVec3Property( + entityHandle: Long, + label: String +): FloatArray? { + TODO("Not yet implemented") +} + +actual fun CustomProperties.setStringProperty( + entityHandle: Long, + label: String, + value: String +) { +} + +actual fun CustomProperties.setIntProperty( + entityHandle: Long, + label: String, + value: Int +) { +} + +actual fun CustomProperties.setLongProperty( + entityHandle: Long, + label: String, + value: Long +) { +} + +actual fun CustomProperties.setFloatProperty( + entityHandle: Long, + label: String, + value: Double +) { +} + +actual fun CustomProperties.setBoolProperty( + entityHandle: Long, + label: String, + value: Boolean +) { +} + +actual fun CustomProperties.setVec3Property( + entityHandle: Long, + label: String, + value: FloatArray +) { +} + +actual fun customPropertiesExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,16 @@ +package com.dropbear + +actual fun getEntity(label: String): Long? { + TODO("Not yet implemented") +} + +actual fun getCamera(label: String): Camera? { + TODO("Not yet implemented") +} + +actual fun getAsset(eucaURI: String): Long? { + TODO("Not yet implemented") +} + +actual fun quit() { +} @@ -0,0 +1,20 @@ +package com.dropbear + +actual fun EntityRef.getEntityLabel(entity: EntityId): String? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getChildren(entityId: EntityId): Array<EntityRef>? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getChildByLabel( + entityId: EntityId, + label: String +): EntityRef? { + TODO("Not yet implemented") +} + +actual fun EntityRef.getParent(entityId: EntityId): EntityRef? { + TODO("Not yet implemented") +} @@ -0,0 +1,31 @@ +package com.dropbear + +import com.dropbear.math.Transform + +actual fun EntityTransform.getLocalTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun EntityTransform.setLocalTransform( + entityId: EntityId, + transform: Transform +) { +} + +actual fun EntityTransform.getWorldTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun EntityTransform.setWorldTransform( + entityId: EntityId, + transform: Transform +) { +} + +actual fun EntityTransform.propagateTransform(entityId: EntityId): Transform { + TODO("Not yet implemented") +} + +actual fun entityTransformExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,37 @@ +package com.dropbear + +import com.dropbear.asset.ModelHandle +import com.dropbear.asset.TextureHandle + +actual fun MeshRenderer.getModel(id: EntityId): ModelHandle? { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setModel(id: EntityId, model: ModelHandle?) { +} + +actual fun MeshRenderer.getAllTextureIds(id: EntityId): List<TextureHandle>? { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.getMaterialNames(id: EntityId): List<String> { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setMaterialNames(id: EntityId, names: Array<String>) { +} + +actual fun MeshRenderer.getTexture(id: EntityId, materialName: String): Long { + TODO("Not yet implemented") +} + +actual fun MeshRenderer.setTextureOverride( + id: EntityId, + materialName: String, + textureHandle: Long +) { +} + +actual fun meshRendererExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,9 @@ +package com.dropbear.asset + +actual fun AssetHandle.asTextureHandle(): TextureHandle? { + TODO("Not yet implemented") +} + +actual fun isModelHandle(id: Long): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,5 @@ +package com.dropbear.asset + +actual fun TextureHandle.getTextureName(id: Long): String? { + TODO("Not yet implemented") +} @@ -1,197 +0,0 @@ -@file:OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class) -@file:Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") - -package com.dropbear.ffi - -import com.dropbear.EntityId -import com.dropbear.exception.DropbearNativeException -import com.dropbear.ffi.generated.ColliderShape -import com.dropbear.ffi.generated.ColliderShape_Box -import com.dropbear.ffi.generated.ColliderShape_Capsule -import com.dropbear.ffi.generated.ColliderShape_Cone -import com.dropbear.ffi.generated.ColliderShape_Cylinder -import com.dropbear.ffi.generated.ColliderShape_Sphere -import com.dropbear.ffi.generated.RigidBodyMode -import com.dropbear.ffi.generated.SceneLoadResult -import com.dropbear.ffi.generated.Vector3D -import com.dropbear.physics.AxisLock -import com.dropbear.physics.Collider -import com.dropbear.physics.Index -import com.dropbear.physics.RigidBody -import com.dropbear.scene.SceneLoadStatus -import kotlinx.cinterop.ExperimentalForeignApi -import kotlin.experimental.ExperimentalNativeApi - -internal fun SceneLoadResult.fromNative(): SceneLoadStatus { - return when (this) { - SceneLoadResult.SCENE_LOAD_PENDING -> SceneLoadStatus.PENDING - SceneLoadResult.SCENE_LOAD_SUCCESS -> SceneLoadStatus.READY - SceneLoadResult.SCENE_LOAD_ERROR -> SceneLoadStatus.FAILED - } -} - -internal fun Vector3D.toKotlin(): com.dropbear.math.Vector3D { - return com.dropbear.math.Vector3D(this.x, this.y, this.z) -} - -internal fun RigidBodyMode.toKotlin(): com.dropbear.physics.RigidBodyMode { - return when (this) { - RigidBodyMode.RIGIDBODY_MODE_DYNAMIC -> com.dropbear.physics.RigidBodyMode.Dynamic - RigidBodyMode.RIGIDBODY_MODE_FIXED -> com.dropbear.physics.RigidBodyMode.Fixed - RigidBodyMode.RIGIDBODY_MODE_KINEMATIC_POSITION -> com.dropbear.physics.RigidBodyMode.KinematicPosition - RigidBodyMode.RIGIDBODY_MODE_KINEMATIC_VELOCITY -> com.dropbear.physics.RigidBodyMode.KinematicVelocity - } -} - -internal fun com.dropbear.ffi.generated.AxisLock.toKotlin(): AxisLock { - return AxisLock( - this.x, - this.y, - this.z, - ) -} - -internal fun com.dropbear.ffi.generated.RigidBody.toKotlin(nativeEngine: NativeEngine): RigidBody { - return RigidBody( - index = Index(this.index.index, this.index.generation), - entity = EntityId(this.entity), - rigidBodyMode = this.mode.toKotlin(), - gravityScale = this.gravity_scale, - canSleep = this.can_sleep, - ccdEnabled = this.ccd_enabled, - linearVelocity = this.linear_velocity.toKotlin(), - angularVelocity = this.angualar_velocity.toKotlin(), - linearDamping = this.linear_damping, - angularDamping = this.angular_damping, - lockTranslation = this.lock_translation.toKotlin(), - lockRotation = this.lock_rotation.toKotlin(), - native = nativeEngine - ) -} - -internal fun RigidBody.populateCStruct(cBody: com.dropbear.ffi.generated.RigidBody) { - cBody.index.index = this.index.index - cBody.index.generation = this.index.generation - cBody.entity = this.entity.id - cBody.mode = when (this.rigidBodyMode) { - com.dropbear.physics.RigidBodyMode.Dynamic -> RigidBodyMode.RIGIDBODY_MODE_DYNAMIC - com.dropbear.physics.RigidBodyMode.Fixed -> RigidBodyMode.RIGIDBODY_MODE_FIXED - com.dropbear.physics.RigidBodyMode.KinematicPosition -> RigidBodyMode.RIGIDBODY_MODE_KINEMATIC_POSITION - com.dropbear.physics.RigidBodyMode.KinematicVelocity -> RigidBodyMode.RIGIDBODY_MODE_KINEMATIC_VELOCITY - } - cBody.gravity_scale = this.gravityScale - cBody.can_sleep = this.canSleep - cBody.ccd_enabled = this.ccdEnabled - - cBody.linear_velocity.x = this.linearVelocity.x - cBody.linear_velocity.y = this.linearVelocity.y - cBody.linear_velocity.z = this.linearVelocity.z - - cBody.angualar_velocity.x = this.angularVelocity.x - cBody.angualar_velocity.y = this.angularVelocity.y - cBody.angualar_velocity.z = this.angularVelocity.z - - cBody.linear_damping = this.linearDamping - cBody.angular_damping = this.angularDamping - - cBody.lock_translation.x = this.lockTranslation.x - cBody.lock_translation.y = this.lockTranslation.y - cBody.lock_translation.z = this.lockTranslation.z - - cBody.lock_rotation.x = this.lockRotation.x - cBody.lock_rotation.y = this.lockRotation.y - cBody.lock_rotation.z = this.lockRotation.z -} - -internal fun ColliderShape.toKotlin(): com.dropbear.physics.ColliderShape { - return when (this.tag) { - ColliderShape_Box -> { - com.dropbear.physics.ColliderShape.Box( - halfExtents = com.dropbear.math.Vector3D( - this.data.box.half_extents.x, - this.data.box.half_extents.y, - this.data.box.half_extents.z - ) - ) - } - ColliderShape_Sphere -> { - com.dropbear.physics.ColliderShape.Sphere(this.data.sphere.radius) - } - ColliderShape_Capsule -> { - com.dropbear.physics.ColliderShape.Capsule(this.data.capsule.half_height, this.data.capsule.radius) - } - ColliderShape_Cylinder -> { - com.dropbear.physics.ColliderShape.Cylinder(this.data.cylinder.half_height, this.data.cylinder.radius) - } - ColliderShape_Cone -> { - com.dropbear.physics.ColliderShape.Cone(this.data.cone.half_height, this.data.cone.radius) - } - else -> throw DropbearNativeException("Unknown collider tag: ${this.tag}") - } -} - -internal fun com.dropbear.ffi.generated.Collider.toKotlin(nativeEngine: NativeEngine): Collider { - return Collider( - index = Index(this.index.index, this.index.generation), - entity = EntityId(this.entity), - colliderShape = this.collider_shape.toKotlin(), - density = this.density, - friction = this.friction, - restitution = this.restitution, - isSensor = this.is_sensor, - translation = this.translation.toKotlin(), - rotation = this.rotation.toKotlin(), - native = nativeEngine, - id = this.id, - ) -} - -internal fun Collider.populateCStruct(struct: com.dropbear.ffi.generated.Collider) { - struct.index.index = this.index.index - struct.index.generation = this.index.generation - struct.entity = this.entity.id - struct.density = this.density - struct.friction = this.friction - struct.restitution = this.restitution - struct.is_sensor = this.isSensor - - struct.translation.x = this.translation.x - struct.translation.y = this.translation.y - struct.translation.z = this.translation.z - - struct.rotation.x = this.rotation.x - struct.rotation.y = this.rotation.y - struct.rotation.z = this.rotation.z - - this.colliderShape.populateCStruct(struct.collider_shape) -} - -internal fun com.dropbear.physics.ColliderShape.populateCStruct(struct: ColliderShape) { - when (this) { - is com.dropbear.physics.ColliderShape.Box -> { - struct.tag = ColliderShape_Box - struct.data.box.half_extents.x = this.halfExtents.x - struct.data.box.half_extents.y = this.halfExtents.y - struct.data.box.half_extents.z = this.halfExtents.z - } - is com.dropbear.physics.ColliderShape.Sphere -> { - struct.tag = ColliderShape_Sphere - struct.data.sphere.radius = this.radius - } - is com.dropbear.physics.ColliderShape.Capsule -> { - struct.tag = ColliderShape_Capsule - struct.data.capsule.half_height = this.halfHeight - struct.data.capsule.radius = this.radius - } - is com.dropbear.physics.ColliderShape.Cylinder -> { - struct.tag = ColliderShape_Cylinder - struct.data.cylinder.half_height = this.halfHeight - struct.data.cylinder.radius = this.radius - } - is com.dropbear.physics.ColliderShape.Cone -> { - struct.tag = ColliderShape_Cone - struct.data.cone.half_height = this.halfHeight - struct.data.cone.radius = this.radius - } - } -} @@ -1,11 +0,0 @@ -package com.dropbear.ffi - -import com.dropbear.DropbearEngine - -actual fun getEntity(label: String): Long? { - TODO("Not yet implemented") -} -actual fun getAsset(eucaURI: String): Long? { - DropbearEngine.native - TODO("Not yet implemented") -} @@ -1,36 +1,15 @@ @file:OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class) @file:Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -/// guys how do i remove the reinterpret error its genuinely pmo and intellij keeps -/// on catching it. - package com.dropbear.ffi -import com.dropbear.Camera -import com.dropbear.EntityId -import com.dropbear.EntityRef -import com.dropbear.EntityTransform -import com.dropbear.asset.TextureHandle import com.dropbear.exception.DropbearNativeException -import com.dropbear.exception.PrematureSceneSwitchException import com.dropbear.exceptionOnError -import com.dropbear.ffi.generated.* -import com.dropbear.input.Gamepad -import com.dropbear.input.GamepadButton -import com.dropbear.input.KeyCode -import com.dropbear.input.MouseButton -import com.dropbear.input.MouseButtonCodes +import com.dropbear.ffi.generated.DropbearContext import com.dropbear.logging.Logger -import com.dropbear.math.Transform -import com.dropbear.math.Vector2D -import com.dropbear.physics.AxisLock -import com.dropbear.physics.Collider -import com.dropbear.physics.Index -import com.dropbear.physics.RigidBody -import com.dropbear.scene.SceneLoadHandle -import com.dropbear.scene.SceneLoadStatus -import com.dropbear.utils.Progress -import kotlinx.cinterop.* +import kotlinx.cinterop.COpaquePointer +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.interpretCPointer import kotlin.experimental.ExperimentalNativeApi actual class NativeEngine { @@ -88,1563 +67,4 @@ actual class NativeEngine { } } } - - actual fun getEntity(label: String): Long? { - val world = worldHandle ?: return null - memScoped { - val outEntity = alloc<LongVar>() - val result = dropbear_get_entity( - label = label, - world_ptr = world.reinterpret(), - out_entity = outEntity.ptr - ) - return if (result == 0) outEntity.value else if (exceptionOnError) { - throw DropbearNativeException("getEntity failed with code: $result") - } else { - println("getEntity failed with code: $result") - null - } - } - } - - actual fun getEntityLabel(entityHandle: Long): String? { - val world = worldHandle ?: return null - memScoped { - val bufferSize = 256 - val outLabel = allocArray<ByteVar>(bufferSize) - - val result = dropbear_get_entity_name( - world_ptr = world.reinterpret(), - entity_id = entityHandle, - out_name = outLabel, - max_len = bufferSize.toULong() - ) - - if (result == 0) { - return outLabel.toKString() - } else { - if (exceptionOnError) { - throw DropbearNativeException("getEntityLabel failed with code for entity '$entityHandle': $result") - } else { - println("getEntityLabel failed with code: $result") - return null - } - } - } - } - - actual fun getTransform(entityId: EntityId): EntityTransform? { - val world = worldHandle ?: return null - memScoped { - val outTransform = alloc<NativeEntityTransform>() - val result = dropbear_get_transform( - world_ptr = world.reinterpret(), - entity_handle = entityId.id, - out_transform = outTransform.ptr - ) - if (result == 0) { - return EntityTransform( - local = Transform( - position = com.dropbear.math.Vector3D( - outTransform.local.position_x, - outTransform.local.position_y, - outTransform.local.position_z - ), - rotation = com.dropbear.math.QuaternionD( - outTransform.local.rotation_x, - outTransform.local.rotation_y, - outTransform.local.rotation_z, - outTransform.local.rotation_w - ), - scale = com.dropbear.math.Vector3D( - outTransform.local.scale_x, outTransform.local.scale_y, - outTransform.local.scale_z - ) - ), - world = Transform( - position = com.dropbear.math.Vector3D( - outTransform.world.position_x, - outTransform.world.position_y, - outTransform.world.position_z - ), - rotation = com.dropbear.math.QuaternionD( - outTransform.world.rotation_x, - outTransform.world.rotation_y, - outTransform.world.rotation_z, - outTransform.world.rotation_w - ), - scale = com.dropbear.math.Vector3D( - outTransform.world.scale_x, - outTransform.world.scale_y, - outTransform.world.scale_z - ) - ) - ) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getTransform failed with code: $result") - } else { - println("getTransform failed with code: $result") - return null - } - } - } - } - - actual fun propagateTransform(entityId: EntityId): Transform? { - val world = worldHandle ?: return null - memScoped { - val outTransform = alloc<NativeTransform>() - val result = dropbear_propagate_transform( - world_ptr = world.reinterpret(), - entity_id = entityId.id, - out_transform = outTransform.ptr - ) - if (result == 0) { - return Transform( - position = com.dropbear.math.Vector3D( - outTransform.position_x, - outTransform.position_y, - outTransform.position_z - ), - rotation = com.dropbear.math.QuaternionD( - outTransform.rotation_x, - outTransform.rotation_y, - outTransform.rotation_z, - outTransform.rotation_w - ), - scale = com.dropbear.math.Vector3D( - outTransform.scale_x, - outTransform.scale_y, - outTransform.scale_z - ) - ) - } else { - if (exceptionOnError) { - throw DropbearNativeException("propagateTransform failed with code: $result") - } else { - println("propagateTransform failed with code: $result") - return null - } - } - } - } - - actual fun setTransform(entityId: EntityId, transform: EntityTransform) { - val worldHandle = worldHandle ?: return - memScoped { - val nativeTransform = cValue<NativeEntityTransform> { - local.position_x = transform.local.position.x - local.position_y = transform.local.position.y - local.position_z = transform.local.position.z - local.rotation_w = transform.local.rotation.w - local.rotation_x = transform.local.rotation.x - local.rotation_y = transform.local.rotation.y - local.rotation_z = transform.local.rotation.z - local.scale_x = transform.local.scale.x - local.scale_y = transform.local.scale.y - local.scale_z = transform.local.scale.z - - world.position_x = transform.world.position.x - world.position_y = transform.world.position.y - world.position_z = transform.world.position.z - world.rotation_w = transform.world.rotation.w - world.rotation_x = transform.world.rotation.x - world.rotation_y = transform.world.rotation.y - world.rotation_z = transform.world.rotation.z - world.scale_x = transform.world.scale.x - world.scale_y = transform.world.scale.y - world.scale_z = transform.world.scale.z - } - - val result = dropbear_set_transform( - world_ptr = worldHandle.reinterpret(), - entity_id = entityId.id, - transform = nativeTransform - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setTransform failed with code: $result") - } else { - println("setTransform failed with code: $result") - } - } - } - } - - actual fun printInputState() { - val input = inputHandle ?: return - dropbear_print_input_state(input_ptr = input.reinterpret()) - } - - actual fun isKeyPressed(key: KeyCode): Boolean { - val input = inputHandle ?: return false - memScoped { - val out = alloc<IntVar>() - val result = dropbear_is_key_pressed( - input.reinterpret(), - key.ordinal, - out.ptr - ) - return if (result == 0) out.value != 0 else if (exceptionOnError) { - throw DropbearNativeException("isKeyPressed failed with code: $result") - } else { - println("isKeyPressed failed with code: $result") - false - } - } - } - - actual fun getMousePosition(): Vector2D? { - val input = inputHandle ?: return null - memScoped { - val xVar = alloc<FloatVar>() - val yVar = alloc<FloatVar>() - - val result = dropbear_get_mouse_position( - input.reinterpret(), - xVar.ptr, - yVar.ptr - ) - - if (result == 0) { - val x = xVar.value.toDouble() - val y = yVar.value.toDouble() - return Vector2D(x, y) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getMousePosition failed with code: $result") - } else { - println("getMousePosition failed with code: $result") - return null - } - } - } - } - - actual fun isMouseButtonPressed(button: MouseButton): Boolean { - val buttonCode: Int = when (button) { - MouseButton.Left -> MouseButtonCodes.LEFT - MouseButton.Right -> MouseButtonCodes.RIGHT - MouseButton.Middle -> MouseButtonCodes.MIDDLE - MouseButton.Back -> MouseButtonCodes.BACK - MouseButton.Forward -> MouseButtonCodes.FORWARD - is MouseButton.Other -> button.value - } - - val input = inputHandle ?: return false - - memScoped { - val pressedVar = alloc<IntVar>() - - val result = dropbear_is_mouse_button_pressed( - input.reinterpret(), - buttonCode, - pressedVar.ptr - ) - - if (result == 0) { - return pressedVar.value != 0 - } else { - if (exceptionOnError) { - throw DropbearNativeException("isMouseButtonPressed failed with code: $result") - } else { - println("isMouseButtonPressed failed with code: $result") - return false - } - } - } - } - - actual fun getMouseDelta(): Vector2D? { - val input = inputHandle ?: return null - memScoped { - val deltaXVar = alloc<FloatVar>() - val deltaYVar = alloc<FloatVar>() - - val result = dropbear_get_mouse_delta( - input.reinterpret(), - deltaXVar.ptr, - deltaYVar.ptr - ) - - if (result == 0) { - val deltaX = deltaXVar.value.toDouble() - val deltaY = deltaYVar.value.toDouble() - return Vector2D(deltaX, deltaY) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getMouseDelta failed with code: $result") - } else { - println("getMouseDelta failed with code: $result") - return null - } - } - } - } - - actual fun isCursorLocked(): Boolean { - val input = inputHandle ?: return false - memScoped { - val lockedVar = alloc<IntVar>() - - val result = dropbear_is_cursor_locked( - input.reinterpret(), - lockedVar.ptr - ) - - if (result == 0) { - return lockedVar.value != 0 - } else { - if (exceptionOnError) { - throw DropbearNativeException("isCursorLocked failed with code: $result") - } else { - println("isCursorLocked failed with code: $result") - return false - } - } - } - } - - actual fun setCursorLocked(locked: Boolean) { - val lockedInt = if (locked) 1 else 0 - val input = inputHandle ?: return - val graphics = commandBufferHandle ?: return - - val result = dropbear_set_cursor_locked( - input.reinterpret(), - graphics.reinterpret(), - lockedInt - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setCursorLocked failed with code: $result") - } else { - println("setCursorLocked failed with code: $result") - } - } - } - - actual fun getLastMousePos(): Vector2D? { - val input = inputHandle ?: return null - memScoped { - val xVar = alloc<FloatVar>() - val yVar = alloc<FloatVar>() - - val result = dropbear_get_last_mouse_pos( - input.reinterpret(), - xVar.ptr, - yVar.ptr - ) - - if (result == 0) { - val x = xVar.value.toDouble() - val y = yVar.value.toDouble() - return Vector2D(x, y) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getLastMousePos failed with code: $result") - } else { - println("getLastMousePos failed with code: $result") - return null - } - } - } - } - - actual fun isCursorHidden(): Boolean { - val input = inputHandle ?: return false - memScoped { - val hiddenVar = alloc<IntVar>() - - val result = dropbear_is_cursor_hidden( - input.reinterpret(), - hiddenVar.ptr - ) - - if (result == 0) { - return hiddenVar.value != 0 - } else { - if (exceptionOnError) { - throw DropbearNativeException("isCursorHidden failed with code: $result") - } else { - println("isCursorHidden failed with code: $result") - return false - } - } - } - } - - actual fun setCursorHidden(hidden: Boolean) { - val hiddenInt = if (hidden) 1 else 0 - val input = inputHandle ?: return - val graphics = commandBufferHandle ?: return - - val result = dropbear_set_cursor_hidden( - input.reinterpret(), - graphics.reinterpret(), - hiddenInt - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setCursorHidden failed with code: $result") - } else { - println("setCursorHidden failed with code: $result") - } - } - } - - actual fun getConnectedGamepads(): List<Gamepad> { - val input = inputHandle ?: return emptyList() - memScoped { - val gamepadsPtr = alloc<CPointerVar<com.dropbear.ffi.generated.Gamepad>>() - val count = alloc<IntVar>() - - val result = dropbear_get_connected_gamepads( - input.reinterpret(), - gamepadsPtr.ptr, - count.ptr - ) - - if (result == 0) { - val gamepadArray = gamepadsPtr.value - val gamepadCount = count.value - - if (gamepadArray == null || gamepadCount == 0) { - return emptyList() - } - - return List(gamepadCount) { index -> - val nativeGamepad = gamepadArray[index] - Gamepad( - id = nativeGamepad.id.toLong(), - leftStickPosition = Vector2D( - x = nativeGamepad.left_stick_pos.x, - y = nativeGamepad.left_stick_pos.y - ), - rightStickPosition = Vector2D( - x = nativeGamepad.right_stick_pos.x, - y = nativeGamepad.right_stick_pos.y - ), - native = this@NativeEngine - ) - } - } else { - if (exceptionOnError) { - throw DropbearNativeException("getConnectedGamepads failed with code: $result") - } else { - println("getConnectedGamepads failed with code: $result") - return emptyList() - } - } - } - } - - actual fun isGamepadButtonPressed(id: Long, button: GamepadButton): Boolean { - val input = inputHandle ?: return false - memScoped { - val outPressed = alloc<IntVar>() - - val result = dropbear_is_gamepad_button_pressed( - input_ptr = input.reinterpret(), - gamepad_id = id, - ordinal = button.ordinal, - out_pressed = outPressed.ptr - ) - - return if (result == 0) { - outPressed.value != 0 - } else if (exceptionOnError) { - throw DropbearNativeException( - "isGamepadButtonPressed failed for gamepadId='$id' button='${button.name}' with code: $result" - ) - } else { - println( - "isGamepadButtonPressed failed for gamepadId='$id' button='${button.name}' with code: $result" - ) - false - } - } - } - - actual fun getStringProperty(entityHandle: Long, label: String): String? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<CPointerVar<ByteVar>>() - - val result = dropbear_get_string_property( - world.reinterpret(), - entityHandle, - label, - output.ptr - ) - - if (result == 0) { - val string = output.value?.toKString() - return string - } else { - if (exceptionOnError) { - throw DropbearNativeException("getStringProperty [$label] failed with code: $result") - } else { - println("getStringProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getIntProperty(entityHandle: Long, label: String): Int? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<IntVar>() - - val result = dropbear_get_int_property( - world.reinterpret(), - entityHandle, - label, - output.ptr, - ) - - if (result == 0) { - return output.value - } else { - if (exceptionOnError) { - throw DropbearNativeException("getIntProperty [$label] failed with code: $result") - } else { - println("getIntProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getLongProperty(entityHandle: Long, label: String): Long? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<LongVar>() - - val result = dropbear_get_long_property( - world.reinterpret(), - entityHandle, - label, - output.ptr - ) - - if (result == 0) { - return output.value - } else { - if (exceptionOnError) { - throw DropbearNativeException("getLongProperty [$label] failed with code: $result") - } else { - println("getLongProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getFloatProperty(entityHandle: Long, label: String): Float? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<DoubleVar>() - - val result = dropbear_get_float_property( - world.reinterpret(), - entityHandle, - label, - output.ptr - ) - - if (result == 0) { - return output.value.toFloat() - } else { - if (exceptionOnError) { - throw DropbearNativeException("getFloatProperty [$label] failed with code: $result") - } else { - println("getFloatProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getDoubleProperty(entityHandle: Long, label: String): Double? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<DoubleVar>() - - val result = dropbear_get_float_property( - world.reinterpret(), - entityHandle, - label, - output.ptr - ) - - if (result == 0) { - return output.value - } else { - if (exceptionOnError) { - throw DropbearNativeException("getDoubleProperty [$label] failed with code: $result") - } else { - println("getDoubleProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getBoolProperty(entityHandle: Long, label: String): Boolean? { - val world = worldHandle ?: return null - memScoped { - val output = alloc<IntVar>() - - val result = dropbear_get_bool_property( - world.reinterpret(), - entityHandle, - label, - output.ptr - ) - - if (result == 0) { - return output.value != 0 - } else { - if (exceptionOnError) { - throw DropbearNativeException("getBoolProperty [$label] failed with code: $result") - } else { - println("getBoolProperty [$label] failed with code: $result") - return null - } - } - } - } - - actual fun getVec3Property(entityHandle: Long, label: String): FloatArray? { - val world = worldHandle ?: return null - memScoped { - val outVec = alloc<Vector3D>() - - val result = dropbear_get_vec3_property( - world.reinterpret(), - entityHandle, - label, - outVec.ptr - ) - - if (result == 0) { - return floatArrayOf(outVec.x.toFloat(), outVec.y.toFloat(), outVec.z.toFloat()) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getVec3Property [$label] failed with code: $result") - } else { - println("getVec3Property [$label] failed with code: $result") - return null - } - } - } - } - - actual fun setStringProperty(entityHandle: Long, label: String, value: String) { - val world = worldHandle ?: return - - val result = dropbear_set_string_property( - world.reinterpret(), - entityHandle, - label, - value - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setStringProperty [$label] failed with code: $result") - } else { - println("setStringProperty [$label] failed with code: $result") - } - } - } - - actual fun setIntProperty(entityHandle: Long, label: String, value: Int) { - val world = worldHandle ?: return - - val result = dropbear_set_int_property( - world.reinterpret(), - entityHandle, - label, - value - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setIntProperty [$label] failed with code: $result") - } else { - println("setIntProperty [$label] failed with code: $result") - } - } - } - - actual fun setLongProperty(entityHandle: Long, label: String, value: Long) { - val world = worldHandle ?: return - - val result = dropbear_set_long_property( - world.reinterpret(), - entityHandle, - label, - value - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setLongProperty [$label] failed with code: $result") - } else { - println("setLongProperty [$label] failed with code: $result") - } - } - } - - actual fun setFloatProperty(entityHandle: Long, label: String, value: Double) { - val world = worldHandle ?: return - - val result = dropbear_set_float_property( - world.reinterpret(), - entityHandle, - label, - value - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setFloatProperty [$label] failed with code: $result") - } else { - println("setFloatProperty [$label] failed with code: $result") - } - } - } - - actual fun setBoolProperty(entityHandle: Long, label: String, value: Boolean) { - val world = worldHandle ?: return - val intValue = if (value) 1 else 0 - - val result = dropbear_set_bool_property( - world.reinterpret(), - entityHandle, - label, - intValue - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setBoolProperty [$label] failed with code: $result") - } else { - println("setBoolProperty [$label] failed with code: $result") - } - } - } - - actual fun setVec3Property(entityHandle: Long, label: String, value: FloatArray) { - val world = worldHandle ?: return - - if (value.size < 3) { - if (exceptionOnError) { - throw DropbearNativeException("setVec3Property: FloatArray must have at least 3 elements") - } else { - println("setVec3Property: FloatArray must have at least 3 elements") - return - } - } - - memScoped { - val vec = cValue<Vector3D> { - x = value[0].toDouble() - y = value[1].toDouble() - z = value[2].toDouble() - } - - val result = dropbear_set_vec3_property( - world.reinterpret(), - entityHandle, - label, - vec - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setVec3Property [$label] failed with code: $result") - } else { - println("setVec3Property [$label] failed with code: $result") - } - } - } - } - - actual fun getCamera(label: String): Camera? { - val world = worldHandle ?: return null - memScoped { - val outCamera = alloc<NativeCamera>() - - val result = dropbear_get_camera( - world.reinterpret(), - label, - outCamera.ptr - ) - - if (result == 0) { - return Camera( - label = outCamera.label?.toKString() ?: "", - id = EntityId(outCamera.entity_id), - eye = com.dropbear.math.Vector3D( - outCamera.eye.x, - outCamera.eye.y, - outCamera.eye.z - ), - target = com.dropbear.math.Vector3D( - outCamera.target.x, - outCamera.target.y, - outCamera.target.z - ), - up = com.dropbear.math.Vector3D( - outCamera.up.x, - outCamera.up.y, - outCamera.up.z - ), - aspect = outCamera.aspect, - fov_y = outCamera.fov_y, - znear = outCamera.znear, - zfar = outCamera.zfar, - yaw = outCamera.yaw, - pitch = outCamera.pitch, - speed = outCamera.speed, - sensitivity = outCamera.sensitivity - ) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getCamera failed with code: $result") - } else { - println("getCamera failed with code: $result") - return null - } - } - } - } - - actual fun getAttachedCamera(entityId: EntityId): Camera? { - val world = worldHandle ?: return null - memScoped { - val outCamera = alloc<NativeCamera>() - - val result = dropbear_get_attached_camera( - world.reinterpret(), - entityId.id, - outCamera.ptr - ) - - if (result == 0) { - return Camera( - label = outCamera.label?.toKString() ?: "", - id = EntityId(outCamera.entity_id), - eye = com.dropbear.math.Vector3D( - outCamera.eye.x, - outCamera.eye.y, - outCamera.eye.z - ), - target = com.dropbear.math.Vector3D( - outCamera.target.x, - outCamera.target.y, - outCamera.target.z - ), - up = com.dropbear.math.Vector3D( - outCamera.up.x, - outCamera.up.y, - outCamera.up.z - ), - aspect = outCamera.aspect, - fov_y = outCamera.fov_y, - znear = outCamera.znear, - zfar = outCamera.zfar, - yaw = outCamera.yaw, - pitch = outCamera.pitch, - speed = outCamera.speed, - sensitivity = outCamera.sensitivity - ) - } else { - if (exceptionOnError) { - throw DropbearNativeException("getAttachedCamera failed with code: $result") - } else { - println("getAttachedCamera failed with code: $result") - return null - } - } - } - } - - actual fun setCamera(camera: Camera) { - val world = worldHandle ?: return - memScoped { - val nativeCamera = cValue<NativeCamera> { - label = camera.label.cstr.ptr - entity_id = camera.id.id - - eye.x = camera.eye.x - eye.y = camera.eye.y - eye.z = camera.eye.z - - target.x = camera.target.x - target.y = camera.target.y - target.z = camera.target.z - - up.x = camera.up.x - up.y = camera.up.y - up.z = camera.up.z - - aspect = camera.aspect - fov_y = camera.fov_y - znear = camera.znear - zfar = camera.zfar - - yaw = camera.yaw - pitch = camera.pitch - speed = camera.speed - sensitivity = camera.sensitivity - } - - val result = dropbear_set_camera( - world.reinterpret(), - nativeCamera - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setCamera failed with code: $result") - } else { - println("setCamera failed with code: $result") - } - } - } - } - - actual fun getModel(entityHandle: Long): Long? { - val world = worldHandle ?: return null - val asset = assetHandle ?: return null - memScoped { - val outModel = alloc<LongVar>() - val result = dropbear_get_model( - world.reinterpret(), - asset.reinterpret(), - entityHandle, - outModel.ptr - ) - return if (result == 0) outModel.value else if (exceptionOnError) throw DropbearNativeException("getModel failed with code: $result") else null - } - } - - actual fun setModel(entityHandle: Long, modelHandle: Long) { - val world = worldHandle ?: return - val asset = assetHandle ?: return - - val result = dropbear_set_model( - world.reinterpret(), - asset.reinterpret(), - entityHandle, - modelHandle - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setModel failed with code: $result") - } else { - println("setModel failed with code: $result") - } - } - } - - actual fun getTexture(entityHandle: Long, name: String): Long? { - val world = worldHandle ?: return null - val asset = assetHandle ?: return null - memScoped { - val outTexture = alloc<LongVar>() - val result = dropbear_get_texture( - world.reinterpret(), - asset.reinterpret(), - entityHandle, - name, - outTexture.ptr - ) - return if (result == 0) outTexture.value else if (exceptionOnError) throw DropbearNativeException("getTexture failed with code: $result") else null - } - } - - actual fun isUsingModel(entityHandle: Long, modelHandle: Long): Boolean { - val world = worldHandle ?: return false - memScoped { - val outUsing = alloc<IntVar>() - val result = dropbear_is_using_model( - world.reinterpret(), - entityHandle, - modelHandle, - outUsing.ptr - ) - return if (result == 0) outUsing.value != 0 else false - } - } - - actual fun isUsingTexture(entityHandle: Long, textureHandle: Long): Boolean { - val world = worldHandle ?: return false - memScoped { - val outUsing = alloc<IntVar>() - val result = dropbear_is_using_texture( - world.reinterpret(), - entityHandle, - textureHandle, - outUsing.ptr - ) - return if (result == 0) outUsing.value != 0 else false - } - } - - actual fun getAsset(eucaURI: String): Long? { - val asset = assetHandle ?: return null - memScoped { - val outAsset = alloc<LongVar>() - val result = dropbear_get_asset( - asset.reinterpret(), - eucaURI, - outAsset.ptr - ) - return if (result == 0) outAsset.value else null - } - } - - actual fun isModelHandle(id: Long): Boolean { - val asset = assetHandle ?: return false - memScoped { - val outIsModel = alloc<IntVar>() - val result = dropbear_is_model_handle( - asset.reinterpret(), - id, - outIsModel.ptr - ) - return if (result == 0) outIsModel.value != 0 else false - } - } - - actual fun isTextureHandle(id: Long): Boolean { - val asset = assetHandle ?: return false - memScoped { - val outIsTexture = alloc<IntVar>() - val result = dropbear_is_texture_handle( - asset.reinterpret(), - id, - outIsTexture.ptr - ) - return if (result == 0) outIsTexture.value != 0 else false - } - } - - actual fun setTextureOverride(entityHandle: Long, oldMaterialName: String, newTextureHandle: TextureHandle) { - val world = worldHandle ?: return - val asset = assetHandle ?: return - - val result = dropbear_set_texture( - world.reinterpret(), - asset.reinterpret(), - entityHandle, - oldMaterialName, - newTextureHandle.raw() - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("setTextureOverride failed with code: $result") - } else { - println("setTextureOverride failed with code: $result") - } - } - } - - actual fun getTextureName(textureHandle: Long): String? { - val asset = assetHandle ?: return null - memScoped { - val outName = alloc<CPointerVar<ByteVar>>() - val result = dropbear_get_texture_name( - asset.reinterpret(), - textureHandle, - outName.ptr - ) - return if (result == 0) outName.value?.toKString() else if (exceptionOnError) throw DropbearNativeException("getTextureName failed with code: $result") else null - } - } - - actual fun getAllTextures(entityHandle: Long): Array<String> { - val world = worldHandle ?: return emptyArray() - val asset = assetHandle ?: return emptyArray() - memScoped { - val outTextures = alloc<CPointerVar<CPointerVar<ByteVar>>>() - val outCount = alloc<ULongVar>() - - val result = dropbear_get_all_textures( - asset.reinterpret(), - world.reinterpret(), - entityHandle, - outTextures.ptr, - outCount.ptr - ) - - if (result == 0) { - val count = outCount.value.toInt() - val textureArray = Array(count) { i -> - outTextures.value!![i]?.toKString() ?: "" - } - return textureArray - } else { - if (exceptionOnError) { - throw DropbearNativeException("getAllTextures failed with code: $result") - } else { - println("getAllTextures failed with code: $result") - return emptyArray() - } - } - } - } - - actual fun getChildren(entityId: EntityId): Array<EntityRef>? { - val world = worldHandle ?: return null - memScoped { - val outChildren = alloc<CPointerVar<LongVar>>() - val outCount = alloc<ULongVar>() - - val result = dropbear_get_children( - world.reinterpret(), - entityId.id, - outChildren.ptr, - outCount.ptr - ) - - if (result == 0) { - val count = outCount.value.toInt() - val childArray = Array(count) { i -> - EntityRef(EntityId(outChildren.value!![i])) - } - return childArray - } else { - if (exceptionOnError) { - throw DropbearNativeException("getChildren failed with code: $result") - } else { - println("getChildren failed with code: $result") - return null - } - } - } - } - - actual fun getChildByLabel(entityId: EntityId, label: String): EntityRef? { - val world = worldHandle ?: return null - memScoped { - val outChild = alloc<LongVar>() - val result = dropbear_get_child_by_label( - world.reinterpret(), - entityId.id, - label, - outChild.ptr - ) - return if (result == 0) EntityRef(EntityId(outChild.value)) else if (exceptionOnError) throw DropbearNativeException("getChildByLabel failed with code: $result") else null - } - } - - actual fun getParent(entityId: EntityId): EntityRef? { - val world = worldHandle ?: return null - memScoped { - val outParent = alloc<LongVar>() - val result = dropbear_get_parent( - world.reinterpret(), - entityId.id, - outParent.ptr - ) - return if (result == 0) EntityRef(EntityId(outParent.value)) else if (exceptionOnError) throw DropbearNativeException("getParent failed with code: $result") else null - } - } - - actual fun quit() { - val command = commandBufferHandle ?: if (exceptionOnError) throw DropbearNativeException("Unable to quit: graphicsHandle does not exist") else return - dropbear_quit(command.reinterpret()) - } - - actual fun loadSceneAsync(sceneName: String): SceneLoadHandle? { - val sceneLoader = sceneLoaderHandle ?: if (exceptionOnError) throw DropbearNativeException("sceneLoaderHandle is empty") else return null - val commandBuffer = commandBufferHandle ?: if (exceptionOnError) throw DropbearNativeException("commandBufferHandle is empty") else return null - memScoped { - val outHandle = alloc<com.dropbear.ffi.generated.SceneLoadHandle>() - val result = dropbear_load_scene_async_1( - command_ptr = commandBuffer.reinterpret(), - scene_loader_ptr = sceneLoader.reinterpret(), - name = sceneName, - sceneLoadHandle = outHandle.ptr - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("loadSceneAsync failed with code: $result") - } else { - println("loadSceneAsync failed with code: $result") - } - } - - return SceneLoadHandle( - id = outHandle.id, - sceneName = outHandle.name?.toKString() ?: throw Exception("loadSceneAsync failed: sceneName is null"), - native = this@NativeEngine, - ) - } - } - - actual fun loadSceneAsync(sceneName: String, loadingScene: String): SceneLoadHandle? { - val sceneLoader = sceneLoaderHandle ?: if (exceptionOnError) throw DropbearNativeException("sceneLoaderHandle is empty") else return null - val commandBuffer = commandBufferHandle ?: if (exceptionOnError) throw DropbearNativeException("commandBufferHandle is empty") else return null - memScoped { - val outHandle = alloc<com.dropbear.ffi.generated.SceneLoadHandle>() - val result = dropbear_load_scene_async_2( - command_ptr = commandBuffer.reinterpret(), - scene_loader_ptr = sceneLoader.reinterpret(), - name = sceneName, - loadingScene = loadingScene, - sceneLoadHandle = outHandle.ptr - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("loadSceneAsync with loading scene failed with code: $result") - } else { - println("loadSceneAsync with loading scene failed with code: $result") - } - } - - return SceneLoadHandle( - id = outHandle.id, - sceneName = outHandle.name?.toKString() ?: throw Exception("loadSceneAsync with loading scene failed: sceneName is null"), - native = this@NativeEngine, - ) - } - } - - actual fun switchToSceneAsync(sceneLoadHandle: SceneLoadHandle) { - val command = commandBufferHandle ?: if (exceptionOnError) throw DropbearNativeException("commandBufferHandle is empty") else return - memScoped { - val nativeHandle = alloc<com.dropbear.ffi.generated.SceneLoadHandle>() - nativeHandle.id = sceneLoadHandle.id - nativeHandle.name = sceneLoadHandle.sceneName.cstr.ptr - - val result = dropbear_switch_to_scene_async(command.reinterpret(), nativeHandle.readValue()) - - if (result == -10) { - throw PrematureSceneSwitchException("Attempted to switch to scene before it finished loading") - } - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("switchToSceneAsync failed with code: $result") - } else { - println("switchToSceneAsync failed with code: $result") - } - } - } - } - - actual fun switchToSceneImmediate(sceneName: String) { - val command = commandBufferHandle ?: if (exceptionOnError) throw DropbearNativeException("commandBufferHandle is empty") else return - val result = dropbear_switch_to_scene_immediate( - command_ptr = command.reinterpret(), - name = sceneName, - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("switchToSceneImmediate failed with code: $result") - } else { - println("switchToSceneImmediate failed with code: $result") - } - } - } - - actual fun getSceneLoadProgress(sceneLoadHandle: SceneLoadHandle): Progress { - val sceneLoader = sceneLoaderHandle ?: if (exceptionOnError) throw DropbearNativeException("sceneLoaderHandle is empty") else return Progress.nothing("Error: commandBufferHandle is empty") - memScoped { - val nativeHandle = alloc<com.dropbear.ffi.generated.SceneLoadHandle>() - nativeHandle.id = sceneLoadHandle.id - nativeHandle.name = sceneLoadHandle.sceneName.cstr.ptr - - val outProgress = alloc<com.dropbear.ffi.generated.Progress>() - - val result = dropbear_get_scene_load_progress( - scene_loader_ptr = sceneLoader.reinterpret(), - handle = nativeHandle.readValue(), - progress = outProgress.ptr - ) - - if (result != 0) { - if (exceptionOnError) { - throw DropbearNativeException("getSceneLoadProgress failed with code: $result") - } else { - println("getSceneLoadProgress failed with code: $result") - } - } - - val progress = Progress(outProgress.current, outProgress.total, outProgress.message?.toKString()); - - return progress - } - } - - actual fun getSceneLoadStatus(sceneLoadHandle: SceneLoadHandle): SceneLoadStatus { - val sceneLoader = sceneLoaderHandle ?: if (exceptionOnError) throw DropbearNativeException("sceneLoaderHandle is empty") else return SceneLoadStatus.FAILED - memScoped { - val nativeHandle = alloc<com.dropbear.ffi.generated.SceneLoadHandle>() - nativeHandle.id = sceneLoadHandle.id - nativeHandle.name = sceneLoadHandle.sceneName.cstr.ptr - - val nativeStatus = alloc<SceneLoadResult.Var>() - - val result = dropbear_get_scene_load_status( - scene_loader_ptr = sceneLoader.reinterpret(), - handle = nativeHandle.readValue(), - result = nativeStatus.ptr - ) - if (result == 0) { - return nativeStatus.value.fromNative() - } else { - if (exceptionOnError) { - throw DropbearNativeException("getSceneLoadStatus failed with code: $result") - } else { - println("getSceneLoadStatus failed with code: $result") - return SceneLoadStatus.FAILED - } - } - } - } - - actual fun setPhysicsEnabled(entityId: Long, enabled: Boolean) { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Physics engine handle is null") else return - - val result = dropbear_set_physics_enabled( - world.reinterpret(), - pe.reinterpret(), - entityId, - enabled - ) - - handleResult(result, "setPhysicsEnabled") - } - - actual fun isPhysicsEnabled(entityId: Long): Boolean { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return false - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Physics engine handle is null") else return false - - memScoped { - val outEnabled = alloc<BooleanVar>() - - val result = dropbear_is_physics_enabled( - world.reinterpret(), - pe.reinterpret(), - entityId, - outEnabled.ptr - ) - - if (result != 0) { - handleResult(result, "isPhysicsEnabled") - return false - } - - return outEnabled.value - } - } - - actual fun getRigidBody(entityId: Long): RigidBody? { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return null - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Physics engine handle is null") else return null - - memScoped { - val outRigidBody = alloc<com.dropbear.ffi.generated.RigidBody>() - - val result = dropbear_get_rigidbody( - world.reinterpret(), - pe.reinterpret(), - entityId, - outRigidBody.ptr - ) - - if (result != 0) { - handleResult(result, "getRigidBody") - return null - } - - return outRigidBody.toKotlin(this@NativeEngine) - } - } - - actual fun getAllColliders(entityId: Long): List<Collider> { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return emptyList() - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Physics engine handle is null") else return emptyList() - - memScoped { - val outCollidersPtr = alloc<CPointerVar<com.dropbear.ffi.generated.Collider>>() - val outCount = alloc<UIntVar>() - - val result = dropbear_get_all_colliders( - world.reinterpret(), - pe.reinterpret(), - entityId, - outCollidersPtr.ptr, - outCount.ptr - ) - - if (result != 0) { - handleResult(result, "getAllColliders") - return emptyList() - } - - val count = outCount.value.toInt() - val cArray = outCollidersPtr.value - - if (cArray == null || count == 0) { - return emptyList() - } - - val list = ArrayList<Collider>(count) - for (i in 0 until count) { - val cCollider = cArray[i] - list.add(cCollider.toKotlin(this@NativeEngine)) - } - - dropbear_free_colliders(cArray, outCount.value) - - return list - } - } - - actual fun applyImpulse(index: Index, x: Double, y: Double, z: Double) { - val pe = physicsEngineHandle ?: return - - memScoped { - val cIndex = alloc<com.dropbear.ffi.generated.Index>() - cIndex.index = index.index - cIndex.generation = index.generation - - val cImpulse = alloc<com.dropbear.ffi.generated.Vector3D>() - cImpulse.x = x - cImpulse.y = y - cImpulse.z = z - - dropbear_apply_impulse( - pe.reinterpret(), - cIndex.readValue(), - cImpulse.readValue() - ) - } - } - - actual fun applyTorqueImpulse(index: Index, x: Double, y: Double, z: Double) { - val pe = physicsEngineHandle ?: return - - memScoped { - val cIndex = alloc<com.dropbear.ffi.generated.Index>() - cIndex.index = index.index - cIndex.generation = index.generation - - val cTorque = alloc<Vector3D>() - cTorque.x = x - cTorque.y = y - cTorque.z = z - - dropbear_apply_torque_impulse( - pe.reinterpret(), - cIndex.readValue(), - cTorque.readValue() - ) - } - } - - actual fun setRigidbody(rigidBody: RigidBody) { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Handle null") else return - - memScoped { - val cBody = alloc<com.dropbear.ffi.generated.RigidBody>() - rigidBody.populateCStruct(cBody) - - val result = dropbear_set_rigidbody( - world.reinterpret(), - pe.reinterpret(), - cBody.readValue() - ) - handleResult(result, "setRigidbody") - } - } - - actual fun getChildColliders(index: Index): List<Collider> { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return emptyList() - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Handle null") else return emptyList() - - memScoped { - val cIndex = alloc<com.dropbear.ffi.generated.Index>() - cIndex.index = index.index - cIndex.generation = index.generation - - val outCollidersPtr = alloc<CPointerVar<com.dropbear.ffi.generated.Collider>>() - val outCount = alloc<UIntVar>() - - val result = dropbear_get_child_colliders( - world.reinterpret(), - pe.reinterpret(), - cIndex.readValue(), - outCollidersPtr.ptr, - outCount.ptr - ) - - if (result != 0) { - handleResult(result, "getChildColliders") - return emptyList() - } - - val count = outCount.value.toInt() - val cArray = outCollidersPtr.value - - if (cArray == null || count == 0) return emptyList() - - val list = ArrayList<Collider>(count) - for (i in 0 until count) { - list.add(cArray[i].toKotlin(this@NativeEngine)) - } - - dropbear_free_colliders(cArray, outCount.value) - return list - } - } - - actual fun setCollider(collider: Collider) { - val world = worldHandle ?: if (exceptionOnError) throw DropbearNativeException("world handle null") else return - val pe = physicsEngineHandle ?: if (exceptionOnError) throw DropbearNativeException("Handle null") else return - - memScoped { - val cCollider = alloc<com.dropbear.ffi.generated.Collider>() - collider.populateCStruct(cCollider) - - val result = dropbear_set_collider( - world.reinterpret(), - pe.reinterpret(), - cCollider.readValue() - ) - handleResult(result, "setCollider") - } - } -} - -private fun handleResult(result: Int, funcName: String) { - if (result != 0) { - val msg = "$funcName failed with code: $result" - if (exceptionOnError) { - throw DropbearNativeException(msg) - } else { - Logger.error(msg) - } - } } @@ -0,0 +1,8 @@ +package com.dropbear.input + +actual fun Gamepad.isGamepadButtonPressed( + id: Long, + button: GamepadButton +): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,46 @@ +package com.dropbear.input + +import com.dropbear.math.Vector2D + +actual class InputState actual constructor() { + actual fun printInputState() { + } + + actual fun isKeyPressed(key: KeyCode): Boolean { + TODO("Not yet implemented") + } + + actual fun getMousePosition(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isMouseButtonPressed(button: MouseButton): Boolean { + TODO("Not yet implemented") + } + + actual fun getMouseDelta(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isCursorLocked(): Boolean { + TODO("Not yet implemented") + } + + actual fun setCursorLocked(locked: Boolean) { + } + + actual fun getLastMousePos(): Vector2D { + TODO("Not yet implemented") + } + + actual fun isCursorHidden(): Boolean { + TODO("Not yet implemented") + } + + actual fun setCursorHidden(hidden: Boolean) { + } + + actual fun getConnectedGamepads(): List<Gamepad> { + TODO("Not yet implemented") + } +} @@ -0,0 +1,80 @@ +package com.dropbear.physics + +import com.dropbear.math.Vector3D + +actual fun Collider.getColliderShape(collider: Collider): ColliderShape { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderShape( + collider: Collider, + shape: ColliderShape +) { +} + +actual fun Collider.setColliderDensity( + collider: Collider, + density: Double +) { +} + +actual fun Collider.getColliderFriction(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderFriction( + collider: Collider, + friction: Double +) { +} + +actual fun Collider.getColliderRestitution(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderRestitution( + collider: Collider, + restitution: Double +) { +} + +actual fun Collider.getColliderIsSensor(collider: Collider): Boolean { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderIsSensor( + collider: Collider, + isSensor: Boolean +) { +} + +actual fun Collider.getColliderTranslation(collider: Collider): Vector3D { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderTranslation( + collider: Collider, + translation: Vector3D +) { +} + +actual fun Collider.getColliderRotation(collider: Collider): Vector3D { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderRotation( + collider: Collider, + rotation: Vector3D +) { +} + +actual fun Collider.getColliderMass(collider: Collider): Double { + TODO("Not yet implemented") +} + +actual fun Collider.setColliderMass(collider: Collider, mass: Double) { +} + +actual fun Collider.getColliderDensity(collider: Collider): Double { + TODO("Not yet implemented") +} @@ -0,0 +1,11 @@ +package com.dropbear.physics + +import com.dropbear.EntityId + +actual fun ColliderGroup.getColliderGroupColliders(colliderGroup: ColliderGroup): List<Collider> { + TODO("Not yet implemented") +} + +actual fun colliderGroupExistsForEntity(entityId: EntityId): Boolean { + TODO("Not yet implemented") +} @@ -0,0 +1,134 @@ +package com.dropbear.physics + +import com.dropbear.EntityId +import com.dropbear.math.Vector3D + +actual fun RigidBody.setRigidbodyMode( + rigidBody: RigidBody, + mode: RigidBodyMode +) { +} + +actual fun RigidBody.getRigidbodyMode(rigidBody: RigidBody): RigidBodyMode { + TODO("Not yet implemented") +} + +actual fun RigidBody.getRigidbodyGravityScale(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyGravityScale( + rigidBody: RigidBody, + gravityScale: Double +) { +} + +actual fun RigidBody.getRigidbodyCanSleep(rigidBody: RigidBody): Boolean { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyCanSleep( + rigidBody: RigidBody, + canSleep: Boolean +) { +} + +actual fun RigidBody.getRigidbodyCcdEnabled(rigidBody: RigidBody): Boolean { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyCcdEnabled( + rigidBody: RigidBody, + ccdEnabled: Boolean +) { +} + +actual fun RigidBody.getRigidbodyLinearVelocity(rigidBody: RigidBody): Vector3D { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLinearDamping( + rigidBody: RigidBody, + linearDamping: Double +) { +} + +actual fun RigidBody.setRigidbodyLinearVelocity( + rigidBody: RigidBody, + linearVelocity: Vector3D +) { +} + +actual fun RigidBody.getRigidbodyAngularVelocity(rigidBody: RigidBody): Vector3D { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyAngularVelocity( + rigidBody: RigidBody, + angularVelocity: Vector3D +) { +} + +actual fun RigidBody.getRigidbodyLinearDamping(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.getRigidbodyAngularDamping(rigidBody: RigidBody): Double { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyAngularDamping( + rigidBody: RigidBody, + angularDamping: Double +) { +} + +actual fun RigidBody.getRigidbodyLockTranslation(rigidBody: RigidBody): AxisLock { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLockTranslation( + rigidBody: RigidBody, + lockTranslation: AxisLock +) { +} + +actual fun RigidBody.getRigidbodyLockRotation(rigidBody: RigidBody): AxisLock { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyLockRotation( + rigidBody: RigidBody, + lockRotation: AxisLock +) { +} + +actual fun RigidBody.getRigidbodyChildren(rigidBody: RigidBody): List<EntityId> { + TODO("Not yet implemented") +} + +actual fun RigidBody.setRigidbodyChildren( + rigidBody: RigidBody, + children: List<EntityId> +) { +} + +actual fun RigidBody.applyImpulse( + index: Index, + x: Double, + y: Double, + z: Double +) { +} + +actual fun RigidBody.applyTorqueImpulse( + index: Index, + x: Double, + y: Double, + z: Double +) { +} + +actual fun rigidBodyExistsForEntity(entityId: EntityId): Index? { + TODO("Not yet implemented") +} @@ -0,0 +1,15 @@ +package com.dropbear.scene + +import com.dropbear.utils.Progress + +actual fun SceneLoadHandle.switchToSceneAsync(): SceneLoadHandle { + TODO("Not yet implemented") +} + +actual fun SceneLoadHandle.getSceneLoadProgress(): Progress { + TODO("Not yet implemented") +} + +actual fun SceneLoadHandle.getSceneLoadStatus(): SceneLoadStatus { + TODO("Not yet implemented") +} @@ -0,0 +1,15 @@ +package com.dropbear.scene + +actual fun SceneManager.loadSceneAsyncNative(sceneName: String): SceneLoadHandle? { + TODO("Not yet implemented") +} + +actual fun SceneManager.loadSceneAsyncNative( + sceneName: String, + loading_scene: String +): SceneLoadHandle? { + TODO("Not yet implemented") +} + +actual fun SceneManager.switchToSceneImmediateNative(sceneName: String) { +}