Added stub FFI
Former-commit-id: 5d11cb5b8100a169c105405e75d58399caf6f57d
This commit is contained in:
parent
1763012732
commit
7100ed91ec
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/target/
|
||||
/mikktspace-sys/target/
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
|
||||
@ -3,7 +3,5 @@ name = "mikktspace"
|
||||
version = "0.1.0"
|
||||
authors = ["Benjamin Wasty <benny.wasty@gmail.com>"]
|
||||
|
||||
[dev-dependencies]
|
||||
mikktspace-sys = { path = "./mikktspace-sys" }
|
||||
|
||||
[dependencies]
|
||||
mikktspace-sys = { path = "./mikktspace-sys" }
|
||||
|
||||
@ -2,5 +2,9 @@
|
||||
name = "mikktspace-sys"
|
||||
version = "0.1.0"
|
||||
authors = ["alteous <alteous@outlook.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
cmake = "0.1"
|
||||
|
||||
[dependencies]
|
||||
|
||||
9
mikktspace-sys/build.rs
Normal file
9
mikktspace-sys/build.rs
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
extern crate cmake;
|
||||
|
||||
fn main() {
|
||||
let dst = cmake::build("libmikktspace");
|
||||
println!("cargo:rustc-link-search=native={}", dst.display());
|
||||
println!("cargo:rustc-link-lib=static=mikktspace");
|
||||
}
|
||||
|
||||
@ -7,4 +7,5 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c11")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG} -ggdb -DDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE} -O2")
|
||||
set(SOURCES mikktspace.h mikktspace.c)
|
||||
add_library(mikktspace SHARED ${SOURCES})
|
||||
add_library(mikktspace STATIC ${SOURCES})
|
||||
install(TARGETS mikktspace ARCHIVE DESTINATION ".")
|
||||
@ -0,0 +1 @@
|
||||
e52ce628fdfe770b52733629d6c2ba6ae871c323
|
||||
136
mikktspace-sys/src/ffi.rs
Normal file
136
mikktspace-sys/src/ffi.rs
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
#![allow(bad_style)]
|
||||
|
||||
use std::os::raw::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub type tbool = c_int;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const TFALSE: tbool = 0;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const TTRUE: tbool = 1;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SMikkTSpaceInterface {
|
||||
/// Returns the number of faces (triangles/quads) on the mesh to be processed.
|
||||
pub m_getNumFaces: extern "C" fn(pContext: *const SMikkTSpaceContext) -> c_int,
|
||||
|
||||
/// Returns the number of vertices on face number iFace
|
||||
/// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
|
||||
pub m_getNumVerticesOfFace: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
iFace: c_int,
|
||||
) -> c_int,
|
||||
|
||||
/// Returns the position of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
pub m_getPosition: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fvPosOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
),
|
||||
|
||||
/// Returns the normal of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
pub m_getNormal: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fvNormOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
),
|
||||
|
||||
/// Returns the texcoord of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
pub m_getTexCoord: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fvTexcOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
),
|
||||
|
||||
/// either (or both) of the two setTSpace callbacks can be set.
|
||||
/// The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
|
||||
|
||||
/// This function is used to return the tangent and fSign to the application.
|
||||
/// fvTangent is a unit length vector.
|
||||
/// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
|
||||
/// bitangent = fSign * cross(vN, tangent);
|
||||
/// Note that the results are returned unindexed. It is possible to generate a new index list
|
||||
/// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
|
||||
/// DO NOT! use an already existing index list.
|
||||
pub m_setTSpaceBasic: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fvTangent: *const c_float,
|
||||
fSign: *const c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
),
|
||||
|
||||
/// This function is used to return tangent space results to the application.
|
||||
/// fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
|
||||
/// true magnitudes which can be used for relief mapping effects.
|
||||
/// fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
|
||||
/// However, both are perpendicular to the vertex normal.
|
||||
/// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
|
||||
/// fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
|
||||
/// bitangent = fSign * cross(vN, tangent);
|
||||
/// Note that the results are returned unindexed. It is possible to generate a new index list
|
||||
/// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
|
||||
/// DO NOT! use an already existing index list.
|
||||
pub m_setTSpace: extern "C" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fvTangent: *const c_float,
|
||||
fvBiTangent: *const c_float,
|
||||
fMagS: *const c_float,
|
||||
fMagT: *const c_float,
|
||||
bIsOrientationPreserving: tbool,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
),
|
||||
}
|
||||
|
||||
/// these are both thread safe!
|
||||
/// Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
|
||||
pub type genTangSpaceDefault = extern "system" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
) -> tbool;
|
||||
|
||||
pub type genTangSpace = extern "system" fn(
|
||||
pContext: *const SMikkTSpaceContext,
|
||||
fAngularThreshold: c_float,
|
||||
) -> tbool;
|
||||
|
||||
/// To avoid visual errors (distortions/unwanted hard edges in lighting), when using sampled normal maps, the
|
||||
/// normal map sampler must use the exact inverse of the pixel shader transformation.
|
||||
/// The most efficient transformation we can possibly do in the pixel shader is
|
||||
/// achieved by using, directly, the "unnormalized" interpolated tangent, bitangent and vertex normal: vT, vB and vN.
|
||||
/// pixel shader (fast transform out)
|
||||
/// vNout = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
|
||||
/// where vNt is the tangent space normal. The normal map sampler must likewise use the
|
||||
/// interpolated and "unnormalized" tangent, bitangent and vertex normal to be compliant with the pixel shader.
|
||||
/// sampler does (exact inverse of pixel shader):
|
||||
/// float3 row0 = cross(vB, vN);
|
||||
/// float3 row1 = cross(vN, vT);
|
||||
/// float3 row2 = cross(vT, vB);
|
||||
/// float fSign = dot(vT, row0)<0 ? -1 : 1;
|
||||
/// vNt = normalize( fSign * float3(dot(vNout,row0), dot(vNout,row1), dot(vNout,row2)) );
|
||||
/// where vNout is the sampled normal in some chosen 3D space.
|
||||
///
|
||||
/// Should you choose to reconstruct the bitangent in the pixel shader instead
|
||||
/// of the vertex shader, as explained earlier, then be sure to do this in the normal map sampler also.
|
||||
/// Finally, beware of quad triangulations. If the normal map sampler doesn't use the same triangulation of
|
||||
/// quads as your renderer then problems will occur since the interpolated tangent spaces will differ
|
||||
/// eventhough the vertex level tangent spaces match. This can be solved either by triangulating before
|
||||
/// sampling/exporting or by using the order-independent choice of diagonal for splitting quads suggested earlier.
|
||||
/// However, this must be used both by the sampler and your tools/rendering pipeline.
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SMikkTSpaceContext {
|
||||
/// initialized with callback functions
|
||||
pub m_pInterface: *const SMikkTSpaceInterface,
|
||||
/// pointer to client side mesh data etc. (passed as the first parameter with every interface call)
|
||||
pub m_pUserData: *const c_void,
|
||||
}
|
||||
@ -1,3 +1,126 @@
|
||||
|
||||
mod ffi;
|
||||
|
||||
use std::os::raw::*;
|
||||
use std::mem;
|
||||
|
||||
const INTERFACE: ffi::SMikkTSpaceInterface = ffi::SMikkTSpaceInterface {
|
||||
m_getNumFaces: faces,
|
||||
m_getNumVerticesOfFace: vertices,
|
||||
m_getPosition: position,
|
||||
m_getNormal: normal,
|
||||
m_getTexCoord: tex_coord,
|
||||
m_setTSpaceBasic: set_tspace_basic,
|
||||
m_setTSpace: set_tspace,
|
||||
};
|
||||
|
||||
pub struct Context {
|
||||
faces: i32,
|
||||
}
|
||||
|
||||
/// Returns the number of faces (triangles/quads) on the mesh to be processed.
|
||||
#[no_mangle]
|
||||
extern "C" fn faces(pContext: *const ffi::SMikkTSpaceContext) -> c_int {
|
||||
unsafe {
|
||||
let m: *const Context = mem::transmute(pContext);
|
||||
(*m).faces as c_int
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of vertices on face number iFace
|
||||
/// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
|
||||
#[no_mangle]
|
||||
extern "C" fn vertices(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
iFace: c_int,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the position of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
#[no_mangle]
|
||||
extern "C" fn position(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
fvPosOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
) {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the normal of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
#[no_mangle]
|
||||
extern "C" fn normal(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
fvPosOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
) {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the texcoord of the referenced face of vertex number
|
||||
/// iVert, in the range {0,1,2} for triangles, and {0,1,2,3} for quads.
|
||||
#[no_mangle]
|
||||
extern "C" fn tex_coord(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
fvTexcOut: *mut c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
) {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the tangent and its sign to the application.
|
||||
#[no_mangle]
|
||||
extern "C" fn set_tspace_basic(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
fvTangent: *const c_float,
|
||||
fSign: *const c_float,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
) {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns tangent space results to the application.
|
||||
#[no_mangle]
|
||||
extern "C" fn set_tspace(
|
||||
pContext: *const ffi::SMikkTSpaceContext,
|
||||
fvTangent: *const c_float,
|
||||
fvBiTangent: *const c_float,
|
||||
fMagS: *const c_float,
|
||||
fMagT: *const c_float,
|
||||
bIsOrientationPreserving: ffi::tbool,
|
||||
iFace: c_int,
|
||||
iVert: c_int,
|
||||
) {
|
||||
unsafe {
|
||||
let _: *const Context = mem::transmute(pContext);
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
Context {
|
||||
faces: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user