Skip to content

Commit

Permalink
Support for virtual filesystems through IOSystem (#10)
Browse files Browse the repository at this point in the history
Remove some LWJGL, IOSystem, fixed collada, Fixed transcription errors in bone weights handling
  • Loading branch information
Hugobros3 authored and nicholaspjohnson committed Mar 30, 2018
1 parent cbe8588 commit d885454
Show file tree
Hide file tree
Showing 24 changed files with 238 additions and 142 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Created by .ignore support plugin (hsz.mobi)
.idea/
.idea/
out
build
.gradle
44 changes: 26 additions & 18 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ apply plugin: 'com.github.johnrengelman.shadow'

dependencies {

compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
compile "org.jetbrains.kotlin:kotlin-reflect"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "org.jetbrains.kotlin:kotlin-reflect"

compile 'com.github.kotlin-graphics:uno-sdk:641ec79aa3d5cf696590276f75b8b89804dc9d09'
implementation 'com.github.kotlin-graphics:uno-sdk:641ec79aa3d5cf696590276f75b8b89804dc9d09'

testCompile 'io.kotlintest:kotlintest:2.0.7'

compile 'io.github.microutils:kotlin-logging:1.4.6'
implementation 'io.github.microutils:kotlin-logging:1.4.6'

// compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
// compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'

compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'

//implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'

switch (OperatingSystem.current()) {
case OperatingSystem.WINDOWS:
ext.lwjglNatives = "natives-windows"
Expand All @@ -54,19 +56,21 @@ dependencies {
ext.lwjglNatives = "natives-macos"
break
}

ext.lwjglVersion = "3.1.5-SNAPSHOT"
compile "org.lwjgl:lwjgl:${lwjglVersion}"
compile "org.lwjgl:lwjgl-glfw:${lwjglVersion}"
compile "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}"
compile "org.lwjgl:lwjgl-openal:${lwjglVersion}"
compile "org.lwjgl:lwjgl-opengl:${lwjglVersion}"
compile "org.lwjgl:lwjgl-stb:${lwjglVersion}"
runtime "org.lwjgl:lwjgl:${lwjglVersion}:${lwjglNatives}"
runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:${lwjglNatives}"
runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:${lwjglNatives}"
runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:${lwjglNatives}"
runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:${lwjglNatives}"
runtime "org.lwjgl:lwjgl-stb:${lwjglVersion}:${lwjglNatives}"
implementation "org.lwjgl:lwjgl:${lwjglVersion}"
implementation "org.lwjgl:lwjgl-glfw:${lwjglVersion}"
implementation "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}"
implementation "org.lwjgl:lwjgl-openal:${lwjglVersion}"
implementation "org.lwjgl:lwjgl-opengl:${lwjglVersion}"
implementation "org.lwjgl:lwjgl-stb:${lwjglVersion}"

testRuntime "org.lwjgl:lwjgl:${lwjglVersion}:${lwjglNatives}"
testRuntime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:${lwjglNatives}"
testRuntime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:${lwjglNatives}"
testRuntime "org.lwjgl:lwjgl-openal:${lwjglVersion}:${lwjglNatives}"
testRuntime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:${lwjglNatives}"
testRuntime "org.lwjgl:lwjgl-stb:${lwjglVersion}:${lwjglNatives}"
}

repositories {
Expand All @@ -86,6 +90,10 @@ task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
}

test {
workingDir = "src/test/resources"
}

artifacts {
archives sourcesJar
archives javadocJar
Expand Down
11 changes: 6 additions & 5 deletions src/main/kotlin/assimp/BaseImporter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ abstract class BaseImporter {
/** Currently set progress handler. */
var progress: ProgressHandler? = null

var ioSystem: IOSystem = ASSIMP.defaultIOSystem
/** Returns whether the class can handle the format of the given file.
*.
* The implementation should be as quick as possible. A check for the file extension is enough. If no suitable
Expand All @@ -33,7 +34,7 @@ abstract class BaseImporter {
* time to examine the contents of the file to be loaded for magic bytes, keywords, etc to be able to load files
* with unknown/not existent file extensions.
* @return true if the class can read this file, false if not. */
abstract fun canRead(file: URI, checkSig: Boolean): Boolean
abstract fun canRead(file: String, pIOHandler: IOSystem, checkSig: Boolean): Boolean

/** Imports the given file and returns the imported data.
* If the import succeeds, ownership of the data is transferred to the caller. If the import fails, null is
Expand All @@ -48,7 +49,7 @@ abstract class BaseImporter {
* exception is thrown somewhere in internReadFile(), this function will catch it and transform it into a suitable
* response to the caller.
*/
fun readFile(imp: Importer, file: URI): AiScene? {
fun readFile(imp: Importer, pIOHandler: IOSystem = ioSystem, filePath: String): AiScene? {
progress = imp.progressHandler
assert(progress != null)

Expand All @@ -60,7 +61,7 @@ abstract class BaseImporter {

// dispatch importing
try {
internReadFile(file, sc)
internReadFile(filePath, pIOHandler, sc)
} catch (err: Exception) {
// extract error description
err.printStackTrace()
Expand Down Expand Up @@ -120,9 +121,9 @@ abstract class BaseImporter {
* @param file Path of the file to be imported.
* @param scene The scene object to hold the imported data. Null is not a valid parameter.
* */
open fun internReadFile(file: String, scene: AiScene) = internReadFile(file.uri, scene)
open fun internReadFile(file: String, pIOHandler: IOSystem = ioSystem, scene: AiScene) = Unit//internReadFile(file.uri, scene)

open fun internReadFile(file: URI, scene: AiScene) = Unit
//open fun internReadFile(file: URI, pIOHandler: IOSystem, scene: AiScene) = Unit

companion object {
/** Extract file extension from a string
Expand Down
31 changes: 31 additions & 0 deletions src/main/kotlin/assimp/DefaultIOSystem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package assimp

import java.io.*

class DefaultIOSystem : IOSystem{
override fun exists(pFile: String) = File(pFile).exists()

override fun open(pFile: String): IOStream {
var file = File(pFile)
println(File(".").absolutePath)
if(!file.exists())
throw IOException("File doesn't exist: "+pFile)


return FileIOStream(file)
}

class FileIOStream(val file: File) : IOStream{
override fun read() = FileInputStream(file)

override fun reader() = BufferedReader(FileReader(file))

override val path: String
get() = file.absolutePath

override val filename: String
get() = file.name

override fun parentPath() = file.parentFile.absolutePath
}
}
17 changes: 17 additions & 0 deletions src/main/kotlin/assimp/IOStream.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package assimp

import java.io.BufferedReader
import java.io.InputStream
import java.io.Reader

interface IOStream {
val path : String

val filename: String

fun read() : InputStream

fun reader() : BufferedReader

fun parentPath() : String
}
14 changes: 14 additions & 0 deletions src/main/kotlin/assimp/IOSystem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package assimp

import java.io.File

/** Interface to the file system. */
interface IOSystem {
fun exists(pFile: String): Boolean

fun open(pFile : String): IOStream

fun close(ioStream: IOStream) = Unit //unused ?

fun getOsSeperator() = File.separator
}
23 changes: 16 additions & 7 deletions src/main/kotlin/assimp/Importer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ constructor() {
}
}

var ioHandler: IOSystem
get() = impl.ioSystem

set(value) { if(value != null) impl.ioSystem = value}

/** Checks whether a default progress handler is active
* A default handler is active as long the application doesn't supply its own custom progress handler via
* setProgressHandler().
Expand Down Expand Up @@ -221,6 +226,8 @@ constructor() {
/** Get the currently set progress handler */
val progressHandler get() = impl.progressHandler

fun readFile(uri: URI, flags: Int = 0) = readFile(uri.path, flags)

/** Reads the given file and returns its contents if successful.
*
* If the call succeeds, the contents of the file are returned as a pointer to an AiScene object. The returned data
Expand All @@ -238,11 +245,12 @@ constructor() {
*
* @note Assimp is able to determine the file format of a file automatically.
*/
fun readFile(file: String, flags: Int = 0) = readFile(file.uri, flags)
//fun readFile(file: URI, flags: Int = 0): AiScene? {
fun readFile(file: String, flags: Int = 0) = readFile(file, ioHandler, flags)

fun readFile(file: URI, flags: Int = 0): AiScene? {
fun readFile(file: String, ioSystem: IOSystem = this.ioHandler, flags: Int = 0): AiScene? {

writeLogOpening(file.path)
writeLogOpening(file)

// Check whether this Importer instance has already loaded a scene. In this case we need to delete the old one
if (impl.scene != null) {
Expand All @@ -251,19 +259,20 @@ constructor() {
}

// First check if the file is accessible at all
if (!file.exists()) {
// handled by exception in IOSystem
/*if (!file.exists()) {
impl.errorString = "Unable to open file \"$file\"."
logger.error { impl.errorString }
return null
}
}*/

// TODO std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
// if (profiler) {
// profiler->BeginRegion("total");
// }

// Find an worker class which can handle the file
val imp = impl.importer.find { it.canRead(file, false) }
val imp = impl.importer.find { it.canRead(file, ioHandler,false) }

if (imp == null) {
// not so bad yet ... try format auto detection.
Expand Down Expand Up @@ -300,7 +309,7 @@ constructor() {
// profiler->BeginRegion("import");
// }

impl.scene = imp.readFile(this, file)
impl.scene = imp.readFile(this, ioHandler, file)
impl.progressHandler.updateFileRead(fileSize, fileSize)

// if (profiler) { TODO
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/assimp/ImporterPimpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class ImporterPimpl {
var progressHandler: ProgressHandler = DefaultProgressHandler()
var isDefaultProgressHandler = true

var ioSystem: IOSystem = DefaultIOSystem()

/** Format-specific importer worker objects - one for each format we can read.*/
val importer = importerInstanceList

Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/assimp/assimp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ val Vec3.isBlack get() = abs(r) < epsilon && abs(g) < epsilon && abs(b) < epsilo

object ASSIMP {

val defaultIOSystem = DefaultIOSystem()

object BUILD {

var DEBUG = true
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/assimp/format/X/XFileImporter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ class XFileImporter : BaseImporter() {

var mBuffer: Pointer<Char> = Pointer<Char>(arrayOf())

override fun canRead(pFile: URI, checkSig: Boolean): Boolean {
override fun canRead(pFile: String, ioSystem: IOSystem, checkSig: Boolean): Boolean {
if (!checkSig) //Check File Extension
return pFile.s.substring(pFile.s.lastIndexOf('.') + 1).toLowerCase() == "x"
return pFile.substring(pFile.lastIndexOf('.') + 1).toLowerCase() == "x"
else //Check file Header
return false
}

override fun internReadFile(pFile: URI, pScene: AiScene) {
override fun internReadFile(pFile: String, ioSystem: IOSystem, pScene: AiScene) {
// Read file into memory
var file = File(pFile)
if (!file.canRead()) throw FileSystemException(file, null, "Failed to open file \$pFile.")
Expand Down
9 changes: 5 additions & 4 deletions src/main/kotlin/assimp/format/assbin/AssbinLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import glm_.*
import java.io.File
import java.io.InputStream
import java.net.URI
import java.net.URL

class AssbinLoader : BaseImporter() {

Expand All @@ -21,12 +22,12 @@ class AssbinLoader : BaseImporter() {
var compressed = false
private val be = false // big endian TODO glm global?

override fun canRead(file: URI, checkSig: Boolean) =
File(file).inputStream().use { i -> "ASSIMP.binary-dump.".all { it.i == i.read() } }
override fun canRead(file: String, ioSystem: IOSystem, checkSig: Boolean) =
ioSystem.open(file).read().use { i -> "ASSIMP.binary-dump.".all { it.i == i.read() } }

override fun internReadFile(file: URI, scene: AiScene) {
override fun internReadFile(file: String, ioSystem: IOSystem, scene: AiScene) {

file.toURL().openStream().use {
ioSystem.open(file).read().use {

it.skip(44) // signature

Expand Down
7 changes: 3 additions & 4 deletions src/main/kotlin/assimp/format/blender/BlenderLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ import java.io.FileOutputStream
import java.io.FileInputStream
import java.util.zip.GZIPInputStream


lateinit var buffer: ByteBuffer

val tokens = "BLENDER"

class BlenderImporter : BaseImporter() {

/** Returns whether the class can handle the format of the given file. */
override fun canRead(file: URI, checkSig: Boolean): Boolean {
override fun canRead(file: String, ioSystem: IOSystem, checkSig: Boolean): Boolean {

val extension = file.extension
val extension = getExtension(file)
if (extension == "blend") return true
else if (extension.isEmpty() || checkSig) {
TODO()
Expand All @@ -46,7 +45,7 @@ class BlenderImporter : BaseImporter() {
maxMinor = 50,
fileExtensions = listOf("blend"))

override fun internReadFile(file: URI, scene: AiScene) {
override fun internReadFile(file: String, ioSystem: IOSystem, scene: AiScene) {

val fileChannel = RandomAccessFile(File(file), "r").channel
buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()).order(ByteOrder.nativeOrder())
Expand Down
Loading

0 comments on commit d885454

Please sign in to comment.