Summary
Simplex3d Data API is designed to simplify access to raw numerical data that defines geometry and textures.
Features
- Seamless integration with Simplex3d Math DSL.
- Simple and convinient API.
- On-the-fly data conversion.
- Support for arrays, direct buffers, and interleaved buffers.
- Specialization for primitive types.
- Integrated with scala.collection.
- Compatible with any native API.
Example
``` import simplex3d.math._ import simplex3d.math.double._ import simplex3d.math.double.functions._
import simplex3d.data._ import simplex3d.data.double._
/* Alternative imports to use float instead of double. import simplex3d.math._ import simplex3d.math.float._ import simplex3d.math.float.functions._
import simplex3d.data._ import simplex3d.data.float._ */
object DataExample {
// How to create DataArrays and interleaved DataViews. def main(args: Array[String]) { val size = 10
// Read as Vec3, the backing store is an array of floats.
val vertex = DataArray[Vec3, RFloat](size)
// Read as Vec3, the backing store is an array of signed shorts.
val normal = DataArray[Vec3, SShort](size)
// Read as Vec4, the backing store is an array of unsigned bytes.
val color = DataArray[Vec4, UByte](size)
// Fill arrays with some random data.
val random = new java.util.Random(1)
def r = random.nextDouble
for (i <- 0 until size) {
vertex(i) = Vec3(r, r, r)*10
normal(i) = normalize(Vec3(r, r, r))
color(i) = Vec4(r, r, r, 1)
}
// interleave the arrays into one byte buffer
val (
interleavedVertex,
interleavedNormal,
interleavedColor
) = interleave(
vertex,
normal,
color
)(vertex.size)
// You can read from and write into interleaved buffers as usual!
interleavedVertex(0) = Vec3.Zero
println(interleavedVertex(0))
// Raw buffer contains the data from all the interleaved buffers.
// You can pass it to OpenGL or another native API.
val bytes = interleavedVertex.rawBuffer
} } ```
Snippets
Integration with Math DSL: ``` def generateNormalLines(vertices: inData[Vec3], normals: inData[Vec3], lines: outData[Vec3]) var i = 0; while (i < vertices.size) { val vertex = vertices(i) // reading Vec3
lines(i*2) = vertex // writing Vec3
lines(i*2 + 1) = vertex + normals(i) // combining math operations and writing
i += 1
}
} ```
Simple and convinient API: ``` // Making an empty sequence backed by a direct buffer: val normals = DataBufferVec3, RFloat
// Wrapping an existing array:
val vertices = DataArray[Vec3, RFloat](array)
// Making a new data array from a list of values:
val points = DataArray[Vec3, RFloat](
Vec3(0, 0, 0),
Vec3(0, 1, 0),
Vec3(1, 1, 0),
Vec3(1, 0, 0)
)
```
On the fly conversion: ``` // Making a sequence backed by an array of normalized unsigned bytes. // The data is converted to range [0, 1] for unsigned and [-1, 1] for signed integral numbers. val color = DataArrayVec4, UByte
var i = 0; while (i < color.size) {
val gradient = (i + 1).toDouble/color.size
// A double vector representing an RGBA color is stored
// as 4 bytes that contain RGBA components, one per byte.
color(i) = Vec4(gradient, gradient, 0, 1)
i += 1
}
```
Aarrays, direct buffers, and interleaved buffers: ``` // A sequence backed by an array: val normals = DataArrayVec3, RFloat
// A sequence backed by a direct buffer:
val vertices = DataBuffer[Vec3, RFloat](100)
// iVertex and iNormal are interleaved and share the same buffer:
val (iVertices, iNormals) = interleave(vertices, normals)(vertices.size)
// Making empty interleaved sequences:
val (emptyVertices, emptyNormals) = interleave(
DataSeq[Vec3, RFloat], DataSeq[Vec3, RFloat]
)(100)
```
Specialization for primitive types: ``` // A sequence of ints, backed by an array of short values. val data = DataArraySInt, SShort
var i = 0; while (i < data.size) {
// No boxing/unboxing takes place:
data(i) = i
}
```
Integration with scala.collection: ``` // A sample transformation. val t = Mat4x3 scale(2) rotateX(radians(30)) translate(Vec3(4, 0, 1))
// Checks if vertices have nan or inf values using forall()
if (vertices.forall(!hasErrors(_))) {
println("No abnormal floating point values found.")
}
// transformed is IndexedSeq[ConstVec3]
val transformed =
// Iterating using scala for-comprehension:
for (vertex <- vertices) yield {
t.transformPoint(vertex)
}
// copying IndexedSeq[Vec3] into DataSeq[Vec3, _]
vertices.put(transformed)
```
Integration with OpenGL: ``` // Sending buffer data with JOGL: gl.glBufferData( GL_ARRAY_BUFFER, vertices.byteCapacity, vertices.bindingBuffer, GL_DYNAMIC_DRAW )
// Defining a vertex pointer with JOGL:
gl.glverticesPointer(
vertices.components, vertices.rawType,
vertices.byteStride, vertices.byteOffset
)
```
Tutorials
Tutorials can be found here.