1 module des.assimp.generator; 2 3 import des.util.logsys; 4 import des.util.stdext.algorithm; 5 6 import des.assimp.mesh; 7 8 /// 9 class SMUniformSurfaceMeshGenerator 10 { 11 mixin ClassLogger; 12 protected: 13 14 /// 15 vec2[] planeCoords( uivec2 res ) 16 { 17 vec2[] ret; 18 19 float sx = 1.0 / res.x; 20 float sy = 1.0 / res.y; 21 22 foreach( y; 0 .. res.y+1 ) 23 foreach( x; 0 .. res.x+1 ) 24 ret ~= vec2( sx * x, sy * y ); 25 26 return ret; 27 } 28 29 /// 30 uint[] triangleStripPlaneIndex( uivec2 res, uint term=uint.max ) 31 { 32 uint[] ret; 33 foreach( y; 0 .. res.y-1 ) 34 { 35 ret ~= [ y*res.x, (y+1)*res.x ]; 36 foreach( x; 1 .. res.x ) 37 ret ~= [ y*res.x+x, (y+1)*res.x+x ]; 38 ret ~= term; 39 } 40 return ret; 41 } 42 43 abstract 44 { 45 vec3[] transformCoords( vec2[] ); 46 vec2[] transformTexCoords( vec2[] ); 47 mat3[] getTangentSpace( vec2[] ); 48 } 49 50 public: 51 52 this() { logger = new InstanceLogger( this ); } 53 54 uivec2 subdiv; 55 56 SMMesh getMesh( string name ) 57 { 58 scope(exit) logger.Debug( "generate mesh '%s'" ); 59 60 auto crd = planeCoords( subdiv ); 61 62 SMMesh m; 63 64 m.name = name; 65 m.type = m.Type.TRIANGLE_STRIP; 66 m.indices = triangleStripPlaneIndex( subdiv+uivec2(1,1) ); 67 m.vertices = transformCoords( crd ); 68 m.texcoords = [ SMTexCoord( 2, cast(float[])transformTexCoords( crd ) ) ]; 69 70 auto ts = getTangentSpace( crd ); 71 72 m.normals = amap!(a=>vec3(a.col(2)))( ts ); 73 m.tangents = amap!(a=>vec3(a.col(0)))( ts ); 74 m.bitangents = amap!(a=>vec3(a.col(1)))( ts ); 75 m.colors = null; 76 77 return m; 78 } 79 } 80 81 //vec3 cylinder( in vec2 c ) pure 82 //{ return vec3( cos(c.x), sin(c.x), c.y ); } 83 84 class SMSphereMeshGenerator : SMUniformSurfaceMeshGenerator 85 { 86 protected: 87 88 import std.math; 89 90 vec3 spheric( in vec2 c ) pure 91 { return vec3( cos(c.x) * sin(c.y), sin(c.x) * sin(c.y), cos(c.y) ); } 92 93 vec2[] truePos( vec2[] crd ) 94 { return amap!( a => a * vec2(PI*2,PI) )( crd ); } 95 96 mat3 tangentSpace( in vec2 c ) 97 { 98 auto t = vec3( cos(c.x), sin(c.x), 0 ); 99 auto n = vec3( cos(c.x) * sin(c.y), sin(c.x) * sin(c.y), cos(c.y) ); 100 return mat3( t,-cross(t,n),n ).T; 101 } 102 103 override 104 { 105 vec3[] transformCoords( vec2[] crd ) 106 { return amap!( a => spheric(a) * radius )( truePos( crd ) ); } 107 108 vec2[] transformTexCoords( vec2[] crd ) { return crd; } 109 110 mat3[] getTangentSpace( vec2[] crd ) 111 { return amap!( a => tangentSpace(a) )( truePos( crd ) ); } 112 } 113 114 public: 115 116 this( float R, uint rx, uint ry ) 117 { 118 subdiv = uivec2(rx,ry); 119 radius = R; 120 } 121 122 float radius; 123 } 124 125 SMMesh smGetSphereMesh( string name, float R, uint rx, uint ry ) 126 { 127 auto gen = new SMSphereMeshGenerator( R, rx, ry ); 128 return gen.getMesh( name ); 129 }