@@ -20,12 +20,9 @@ namespace Polymesh {
2020 * สูตร: f(x) ≈ a*x^2 + b*x + c
2121 * สำหรับช่วง [0.5, 1.0] สัมประสิทธิ์ที่เหมาะสมคือ:
2222 */
23- const a = 1.4545 ;
24- const b = - 4.3636 ;
25- const c = 3.9091 ;
2623
2724 // คำนวณด้วย Horner's Method: (a*x + b)*x + c
28- let y = ( a * x + b ) * x + c ;
25+ let y = ( 1.4545 * x + - 4.3636 ) * x + 3.9091 ;
2926
3027 // 3. Scaling กลับ
3128 return y * scale ;
@@ -85,19 +82,14 @@ namespace Polymesh {
8582 * สูตรพหุนามกำลัง 4 ที่ปรับจูนมาเพื่อช่วง [0.5, 2.0]
8683 * f(x) = a + bx + cx^2 + dx^3 + ex^4
8784 */
88- const a = 0.16541 ;
89- const b = 1.34135 ;
90- const c = - 0.73949 ;
91- const d = 0.29323 ;
92- const e = - 0.05282 ;
9385
9486 // ใช้ Horner's Method เพื่อประหยัดการคูณ (เหลือการคูณแค่ 4 ครั้ง)
9587 // res = (((e*x + d)*x + c)*x + b)*x + a
96- let res = e ;
97- res = res * x + d ;
98- res = res * x + c ;
99- res = res * x + b ;
100- res = res * x + a ;
88+ let res = - 0.05282 ;
89+ res = res * x + 0.29323 ;
90+ res = res * x + - 0.73949 ;
91+ res = res * x + 1.34135 ;
92+ res = res * x + 0.16541 ;
10193
10294 // 3. Scale กลับไปยังค่าเดิม
10395 return res * scale ;
@@ -128,24 +120,23 @@ namespace Polymesh {
128120 let err = dx >> 1 ; // หรือใช้ bit shift >>1 ถ้าต้องการ integer แท้ ๆ
129121
130122 const ystep = y0 < y1 ? 1 : - 1 ;
131- let y = y0 ;
132123
133124 const nextErr = ( ) => {
134125 err -= dy ;
135126 if ( err < 0 )
136- y += ystep ,
127+ y0 += ystep ,
137128 err += dx ;
138129 }
139130
140- for ( let x = x0 ; x <= x1 ; x ++ , nextErr ( ) ) {
131+ for ( ; x0 <= x1 ; x0 ++ , nextErr ( ) ) {
141132 if ( steep ) {
142- if ( y < 0 || x < 0 ) continue ;
143- if ( y >= w || x >= h ) break ;
144- pic . setPixel ( y , x , color ) ;
133+ if ( y0 < 0 || x0 < 0 ) continue ;
134+ if ( y0 >= w || x0 >= h ) break ;
135+ pic . setPixel ( y0 , x0 , color ) ;
145136 } else {
146- if ( x < 0 || y < 0 ) continue ;
147- if ( x >= w || y >= h ) break ;
148- pic . setPixel ( x , y , color ) ;
137+ if ( x0 < 0 || y0 < 0 ) continue ;
138+ if ( x0 >= w || y0 >= h ) break ;
139+ pic . setPixel ( x0 , y0 , color ) ;
149140 }
150141 }
151142 }
@@ -282,9 +273,9 @@ namespace Polymesh {
282273 // ค่า faceOffset > 0 = ผ่อนปรนมากขึ้น (ยาก cull)
283274 // ค่า faceOffset < 0 = เข้มงวดขึ้น (ง่าย cull)
284275
285- const GLOBAL_CULL_BIAS = 0.01 ; // หรือ 0.0001 ขึ้นกับ scale ของคุณ
276+ // const GLOBAL_CULL_BIAS = 0.01; // หรือ 0.0001 ขึ้นกับ scale ของคุณ
286277
287- const CULLED = dot <= ( GLOBAL_CULL_BIAS + ( faceOffset || 0 ) ) ;
278+ const CULLED = dot <= ( 0.01 + ( faceOffset || 0 ) ) ;
288279 if ( faceOffset > 0 ) return ! CULLED
289280 return CULLED
290281 }
@@ -460,7 +451,7 @@ namespace Polymesh {
460451 const wInv = 1 / w , hInv = 1 / h ;
461452 const fromRowBuf = pins . createBuffer ( h ) ;
462453 const emptyHash = fromRowBuf . hash ( 0xffff )
463- const pqu = new Ptl (
454+ const pqu = new pt2_2 (
464455 ( p1 . x - p0 . x ) ,
465456 ( p1 . y - p0 . y ) ,
466457 ( p2 . x - p3 . x ) ,
@@ -471,35 +462,44 @@ namespace Polymesh {
471462 from . getRows ( w - ix - 1 , fromRowBuf )
472463 if ( fromRowBuf . hash ( 0xffff ) === emptyHash ) continue ;
473464 const u0 = ( ix * wInv ) , u1 = ( ( ix + 1 ) * wInv ) ;
474- const qu = [ u0 , u1 ] . map ( u => ( new Ptl (
475- p0 . x + pqu . x0 * u ,
476- p0 . y + pqu . y0 * u ,
477- p3 . x + pqu . x1 * u ,
478- p3 . y + pqu . y1 * u ,
479- ) ) )
480-
481- const pqv = new Ptl (
482- ( qu [ 0 ] . x1 - qu [ 0 ] . x0 ) ,
483- ( qu [ 0 ] . y1 - qu [ 0 ] . y0 ) ,
484- ( qu [ 1 ] . x1 - qu [ 1 ] . x0 ) ,
485- ( qu [ 1 ] . y1 - qu [ 1 ] . y0 ) ,
465+ const qu = new pt2_4 (
466+ p0 . x + pqu . x0 * u0 ,
467+ p0 . y + pqu . y0 * u0 ,
468+ p3 . x + pqu . x1 * u0 ,
469+ p3 . y + pqu . y1 * u0 ,
470+ p0 . x + pqu . x0 * u1 ,
471+ p0 . y + pqu . y0 * u1 ,
472+ p3 . x + pqu . x1 * u1 ,
473+ p3 . y + pqu . y1 * u1 ,
486474 )
487- for ( let sy = 0 ; sy < h ; sy ++ , fromRowBuf . shift ( - 1 ) ) {
475+
476+ const pqv = new pt2_2 (
477+ ( qu . x1 - qu . x0 ) ,
478+ ( qu . y1 - qu . y0 ) ,
479+ ( qu . x3 - qu . x2 ) ,
480+ ( qu . y3 - qu . y2 ) ,
481+ )
482+ for ( let sy = 0 ; sy < h ; sy ++ ) {
488483 const iy = zigzet ( 0 , h - 1 , sy , center )
489- if ( fromRowBuf . hash ( 0xffff ) === emptyHash ) continue ;
490- const color = fromRowBuf [ 0 ]
484+ const color = fromRowBuf [ iy ]
491485 if ( color < 1 ) continue ; // transparent
492486 const v0 = ( iy * hInv ) , v1 = ( ( iy + 1 ) * hInv ) ;
493487 // Map quad on 1 pixel
494- const qv = [ v0 , v0 , v1 , v1 ] . map ( ( v , i ) => { const i_2 = i & 1 ;
495- return new Pt (
496- Math . idiv ( qu [ i_2 ] . x0 + ( i_2 ? pqv . x1 : pqv . x0 ) * v , 1 ) ,
497- Math . idiv ( qu [ i_2 ] . y0 + ( i_2 ? pqv . y1 : pqv . y0 ) * v , 1 )
498- ) } )
499- if ( isOutOfAreaOnAvg ( qv , to . width , to . height ) ) if ( qv . every ( v => isOutOfArea ( v . x , v . y , to . width , to . height ) ) ) continue ; // skipped if out of screen
488+
489+ const qv = new pt2_4 (
490+ ( qu . x0 + ( pqv . x0 ) * v0 ) | 0 ,
491+ ( qu . y0 + ( pqv . y0 ) * v0 ) | 0 ,
492+ ( qu . x2 + ( pqv . x1 ) * v0 ) | 0 ,
493+ ( qu . y2 + ( pqv . y1 ) * v0 ) | 0 ,
494+ ( qu . x0 + ( pqv . x0 ) * v1 ) | 0 ,
495+ ( qu . y0 + ( pqv . y0 ) * v1 ) | 0 ,
496+ ( qu . x2 + ( pqv . x1 ) * v1 ) | 0 ,
497+ ( qu . y2 + ( pqv . y1 ) * v1 ) | 0 ,
498+ )
499+ if ( qv . toArr . every ( v => isOutOfArea ( v . x , v . y , to . width , to . height ) ) ) continue ; // skipped if out of screen
500500 // stamp 2 triangles by pixel
501- helpers . imageFillTriangle ( to , qv [ 1 ] . x , qv [ 1 ] . y , qv [ 0 ] . x , qv [ 0 ] . y , qv [ 3 ] . x , qv [ 3 ] . y , color ) ;
502- helpers . imageFillTriangle ( to , qv [ 2 ] . x , qv [ 2 ] . y , qv [ 0 ] . x , qv [ 0 ] . y , qv [ 3 ] . x , qv [ 3 ] . y , color ) ;
501+ helpers . imageFillTriangle ( to , qv . x1 , qv . y1 , qv . x0 , qv . y0 , qv . x3 , qv . y3 , color ) ;
502+ helpers . imageFillTriangle ( to , qv . x2 , qv . y2 , qv . x0 , qv . y0 , qv . x3 , qv . y3 , color ) ;
503503 //helpers.imageFillPolygon4(to, qd[3].x, qd[3].y, qd[2].x, qd[2].y, qd[0].x, qd[0].y, qd[1].x, qd[1].y, colorIdx);
504504 }
505505 }
@@ -525,10 +525,9 @@ namespace Polymesh {
525525
526526 export const meshDepthZ = ( msh : model ) => {
527527 if ( msh . isDel ( ) ) return NaN ;
528- const pos = camview . pos , rot = camview . rot ;
529- return rotatePoint3Dyxz ( new Vector3 ( msh . pos . x , msh . pos . y , msh . pos . z ) , new Vector3 ( pos . x , pos . y , pos . z ) , new Vector3 ( rot . x , rot . y , rot . z ) ) . z ;
528+ return rotatePoint3Dyxz ( msh . pos . toVector ( ) , camview . pos . toVector ( ) , camview . rot . toVector ( ) ) . z ;
530529 }
531530
532- export const meshDistZ = ( msh : model ) => ( Math . abs ( dist ) / ( Math . abs ( dist ) + meshDepthZ ( msh ) ) )
531+ export const meshDistZ = ( msh : model ) => ( Math . abs ( camview . near ) / ( Math . abs ( camview . near ) + meshDepthZ ( msh ) ) )
533532
534533}
0 commit comments