Skip to content

Instantly share code, notes, and snippets.

@demoth
Created February 12, 2023 23:03
Show Gist options
  • Save demoth/9435baa36980be53c1c3adc7635cc2d3 to your computer and use it in GitHub Desktop.
Save demoth/9435baa36980be53c1c3adc7635cc2d3 to your computer and use it in GitHub Desktop.
Q2 mdl to obj converter
package shaders
fun convertToObj(model: Md2Model, frameIndex: Int): String {
val result = StringBuilder()
val frame = model.frames[frameIndex] ?: return ""
result.appendLine("mtllib sphere.mtl")
result.appendLine("o testModel")
// v vec3_position
frame.points.forEach {
result.appendLine("v ${it.x * frame.scale[0]} ${it.z * frame.scale[2]} ${it.y * frame.scale[1]}")
}
// vn vec3_normal
// optional
// result.appendLine("# test texture normals")
// result.appendLine("vn 0.0 1.0 0.0")
// // vt vec2_textureCoords
// result.appendLine("# test texture coords")
// result.appendLine("vt 0.0 0.0")
// result.appendLine("vt 1.0 0.0")
// result.appendLine("vt 0.0 1.0")
result.appendLine("# smoothing groop")
result.appendLine("s 0")
result.appendLine("usemtl IcosphereMaterial")
// f position/normal/texture
var glCmdIndex = 0 // todo: use queue to pop elements instead of using mutable index?
while (true) {
val numOfPoints = model.glCmds[glCmdIndex]
glCmdIndex++
glCmdIndex += if (numOfPoints == 0) {
break
} else if (numOfPoints >= 0) {
// triangle strip
val vertices = mutableListOf<Int>()
for (i in glCmdIndex until (glCmdIndex + numOfPoints * 3) step 3) {
vertices.add(model.glCmds[i + 2])
}
// obj indices are is 1 based, converting strips into separate triangles
vertices.map { it + 1 }.windowed(3).forEach {
result.appendLine("f ${it[0]} ${it[1]} ${it[2]}")
}
numOfPoints * 3
} else {
// triangle fan
val vertices = mutableListOf<Int>()
for (i in glCmdIndex until (glCmdIndex - numOfPoints * 3) step 3) {
vertices.add(model.glCmds[i + 2])
}
// obj indices are is 1 based
convertStripToTriangles(vertices).map { it + 1 }.windowed(3).forEach {
result.appendLine("f ${it[0]} ${it[1]} ${it[2]}")
}
(-numOfPoints * 3)
}
}
return result.toString()
}
private fun convertStripToTriangles(vertices: List<Int>): List<Int> {
val result = mutableListOf<Int>()
vertices.drop(1).windowed(2).forEach {
result.add(vertices.first())
result.add(it.first())
result.add(it.last())
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment