~ubuntu-branches/ubuntu/utopic/blender/utopic-proposed

« back to all changes in this revision

Viewing changes to intern/cycles/kernel/kernel_bvh.h

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-02-19 11:24:23 UTC
  • mfrom: (14.2.23 sid)
  • Revision ID: package-import@ubuntu.com-20140219112423-rkmaz2m7ha06d4tk
Tags: 2.69-3ubuntu1
* Merge with Debian; remaining changes:
  - Configure without OpenImageIO on armhf, as it is not available on
    Ubuntu.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 */
27
27
 
28
28
/* bottom-most stack entry, indicating the end of traversal */
29
 
 
30
29
#define ENTRYPOINT_SENTINEL 0x76543210
 
30
 
31
31
/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
32
32
#define BVH_STACK_SIZE 192
33
33
#define BVH_NODE_SIZE 4
215
215
        float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
216
216
{
217
217
        float epsilon = 0.0f;
218
 
        int depth = kernel_data.curve_kernel_data.subdivisions;
 
218
        float r_st, r_en;
219
219
 
220
 
        /* curve Intersection check */
221
 
        float3 dir = 1.0f/idir;
 
220
        int depth = kernel_data.curve.subdivisions;
 
221
        int flags = kernel_data.curve.curveflags;
 
222
        int prim = kernel_tex_fetch(__prim_index, curveAddr);
222
223
        
223
 
        int flags = kernel_data.curve_kernel_data.curveflags;
224
 
 
225
 
        int prim = kernel_tex_fetch(__prim_index, curveAddr);
226
 
 
227
224
        float3 curve_coef[4];
228
 
        float r_st,r_en;
229
 
 
230
 
        /*obtain curve parameters*/
 
225
 
 
226
        /* curve Intersection check */
 
227
        float3 dir = 1.0f/idir;
 
228
 
 
229
        /* obtain curve parameters */
231
230
        {
232
 
                /*ray transform created - this should be created at beginning of intersection loop*/
 
231
                /* ray transform created - this should be created at beginning of intersection loop */
233
232
                Transform htfm;
234
233
                float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
235
234
                htfm = make_transform(
271
270
        if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
272
271
                epsilon = 2 * r_curr;
273
272
 
274
 
        /*find bounds - this is slow for cubic curves*/
275
 
        float upper,lower;
 
273
        /* find bounds - this is slow for cubic curves */
 
274
        float upper, lower;
276
275
 
277
276
        float zextrem[4];
278
277
        curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
279
278
        if(lower - r_curr > isect->t || upper + r_curr < epsilon)
280
279
                return false;
281
280
 
282
 
        /*minimum width extension*/
 
281
        /* minimum width extension */
283
282
        float mw_extension = min(difl * fabsf(upper), extmax);
284
283
        float r_ext = mw_extension + r_curr;
285
284
 
293
292
        if(lower > r_ext || upper < -r_ext)
294
293
                return false;
295
294
 
296
 
        /*setup recurrent loop*/
 
295
        /* setup recurrent loop */
297
296
        int level = 1 << depth;
298
297
        int tree = 0;
299
298
        float resol = 1.0f / (float)level;
300
299
        bool hit = false;
301
300
 
302
 
        /*begin loop*/
 
301
        /* begin loop */
303
302
        while(!(tree >> (depth))) {
304
303
                float i_st = tree * resol;
305
304
                float i_en = i_st + (level * resol);
347
346
                float coverage = 1.0f;
348
347
 
349
348
                if (bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
350
 
                        /* the bounding box does not overlap the square centered at O.*/
 
349
                        /* the bounding box does not overlap the square centered at O */
351
350
                        tree += level;
352
351
                        level = tree & -tree;
353
352
                }
369
368
                                w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
370
369
                                w = clamp((float)w, 0.0f, 1.0f);
371
370
 
372
 
                                /* compute u on the curve segment.*/
 
371
                                /* compute u on the curve segment */
373
372
                                u = i_st * (1 - w) + i_en * w;
374
373
                                r_curr = r_st + (r_en - r_st) * u;
375
 
                                /* compare x-y distances.*/
 
374
                                /* compare x-y distances */
376
375
                                float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
377
376
 
378
377
                                float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
412
411
                                        level = tree & -tree;
413
412
                                        continue;
414
413
                                }
415
 
                                /* compare z distances.*/
 
414
                                /* compare z distances */
416
415
                                if (isect->t < p_curr.z) {
417
416
                                        tree++;
418
417
                                        level = tree & -tree;
422
421
                        }
423
422
                        else {
424
423
                                float l = len(p_en - p_st);
425
 
                                /*minimum width extension*/
 
424
                                /* minimum width extension */
426
425
                                float or1 = r1;
427
426
                                float or2 = r2;
428
427
                                if(difl != 0.0f) {
445
444
                                float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
446
445
                                float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
447
446
                                float td = tb*tb - 4*cyla*tc;
448
 
                                if (td < 0.0f){
 
447
                                if (td < 0.0f) {
449
448
                                        tree++;
450
449
                                        level = tree & -tree;
451
450
                                        continue;
477
476
                                }
478
477
 
479
478
                                w = clamp((float)w, 0.0f, 1.0f);
480
 
                                /* compute u on the curve segment.*/
 
479
                                /* compute u on the curve segment */
481
480
                                u = i_st * (1 - w) + i_en * w;
482
481
                                r_curr = r1 + (r2 - r1) * w;
483
482
                                r_ext = or1 + (or2 - or1) * w;
484
483
                                coverage = r_curr/r_ext;
485
484
 
486
485
                        }
487
 
                        /* we found a new intersection.*/
 
486
                        /* we found a new intersection */
488
487
 
489
 
                        /*stochastic fade from minimum width*/
 
488
                        /* stochastic fade from minimum width */
490
489
                        if(lcg_state && coverage != 1.0f) {
491
 
                                if(lcg_step(lcg_state) > coverage)
 
490
                                if(lcg_step_float(lcg_state) > coverage)
492
491
                                        return hit;
493
492
                        }
494
493
 
525
524
        float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
526
525
{
527
526
        /* curve Intersection check */
528
 
        int flags = kernel_data.curve_kernel_data.curveflags;
 
527
        int flags = kernel_data.curve.curveflags;
529
528
 
530
529
        int prim = kernel_tex_fetch(__prim_index, curveAddr);
531
530
        float4 v00 = kernel_tex_fetch(__curves, prim);
542
541
        float3 p1 = float4_to_float3(P1);
543
542
        float3 p2 = float4_to_float3(P2);
544
543
 
545
 
        /*minimum width extension*/
 
544
        /* minimum width extension */
546
545
        float r1 = or1;
547
546
        float r2 = or2;
548
547
        if(difl != 0.0f) {
567
566
        if(sdisc < 0.0f)
568
567
                return false;
569
568
 
570
 
        /* obtain parameters and test midpoint distance for suitable modes*/
 
569
        /* obtain parameters and test midpoint distance for suitable modes */
571
570
        float3 tg = (p2 - p1) / l;
572
571
        float gd = (r2 - r1) / l;
573
572
        float dirz = dot(dir,tg);
584
583
        if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
585
584
                return false;
586
585
 
587
 
        /* test minimum separation*/
 
586
        /* test minimum separation */
588
587
        float3 cprod = cross(tg, dir);
589
588
        float3 cprod2 = cross(tg, dif);
590
589
        float cprodsq = len_squared(cprod);
599
598
        if(distscaled > mr*mr)
600
599
                return false;
601
600
 
602
 
        /* calculate true intersection*/
 
601
        /* calculate true intersection */
603
602
        float3 tdif = P - p1 + tcentre * dir;
604
603
        float tdifz = dot(tdif,tg);
605
604
        float tb = 2*(dot(dir,tdif) - dirz*(tdifz + gd*(tdifz*gd + r1)));
636
635
                        z = zcentre + (dirz * correction);
637
636
                }
638
637
 
639
 
                /*stochastic fade from minimum width*/
 
638
                /* stochastic fade from minimum width */
640
639
                float adjradius = or1 + z * (or2 - or1) / l;
641
640
                adjradius = adjradius / (r1 + z * gd);
642
641
                if(lcg_state && adjradius != 1.0f) {
643
 
                        if(lcg_step(lcg_state) > adjradius)
 
642
                        if(lcg_step_float(lcg_state) > adjradius)
644
643
                                return false;
645
644
                }
646
645
                /* --- */
649
648
 
650
649
                        if (flags & CURVE_KN_ENCLOSEFILTER) {
651
650
 
652
 
                                float enc_ratio = kernel_data.curve_kernel_data.encasing_ratio;
 
651
                                float enc_ratio = kernel_data.curve.encasing_ratio;
653
652
                                if((dot(P - p1, tg) > -r1 * enc_ratio) && (dot(P - p2, tg) < r2 * enc_ratio)) {
654
653
                                        float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
655
654
                                        float c2 = dot(dif,dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
690
689
 * only want to intersect with primitives in the same object, and if case of
691
690
 * multiple hits we pick a single random primitive as the intersection point. */
692
691
 
693
 
__device_inline bool bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect,
694
 
        float3 P, float3 idir, int object, int triAddr, float tmax, int *num_hits, float subsurface_random)
 
692
__device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
 
693
        float3 P, float3 idir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
695
694
{
696
695
        /* compute and check intersection t-value */
697
696
        float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
718
717
                        if(v >= 0.0f && u + v <= 1.0f) {
719
718
                                (*num_hits)++;
720
719
 
721
 
                                if(subsurface_random * (*num_hits) <= 1.0f) {
722
 
                                        /* record intersection */
723
 
                                        isect->prim = triAddr;
724
 
                                        isect->object = object;
725
 
                                        isect->u = u;
726
 
                                        isect->v = v;
727
 
                                        isect->t = t;
728
 
                                        return true;
729
 
                                }
 
720
                                int hit;
 
721
 
 
722
                                if(*num_hits <= max_hits) {
 
723
                                        hit = *num_hits - 1;
 
724
                                }
 
725
                                else {
 
726
                                        /* reservoir sampling: if we are at the maximum number of
 
727
                                         * hits, randomly replace element or skip it */
 
728
                                        hit = lcg_step_uint(lcg_state) % *num_hits;
 
729
 
 
730
                                        if(hit >= max_hits)
 
731
                                                return;
 
732
                                }
 
733
 
 
734
                                /* record intersection */
 
735
                                Intersection *isect = &isect_array[hit];
 
736
                                isect->prim = triAddr;
 
737
                                isect->object = object;
 
738
                                isect->u = u;
 
739
                                isect->v = v;
 
740
                                isect->t = t;
730
741
                        }
731
742
                }
732
743
        }
733
 
 
734
 
        return false;
735
744
}
736
745
#endif
737
746
 
741
750
#define BVH_MOTION                              2
742
751
#define BVH_HAIR                                4
743
752
#define BVH_HAIR_MINIMUM_WIDTH  8
744
 
#define BVH_SUBSURFACE                  16
745
753
 
746
754
#define BVH_FUNCTION_NAME bvh_intersect
747
755
#define BVH_FUNCTION_FEATURES 0
773
781
 
774
782
#if defined(__SUBSURFACE__)
775
783
#define BVH_FUNCTION_NAME bvh_intersect_subsurface
776
 
#define BVH_FUNCTION_FEATURES BVH_SUBSURFACE
777
 
#include "kernel_bvh_traversal.h"
 
784
#define BVH_FUNCTION_FEATURES 0
 
785
#include "kernel_bvh_subsurface.h"
778
786
#endif
779
787
 
780
788
#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
781
789
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_instancing
782
 
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE
783
 
#include "kernel_bvh_traversal.h"
 
790
#define BVH_FUNCTION_FEATURES BVH_INSTANCING
 
791
#include "kernel_bvh_subsurface.h"
784
792
#endif
785
793
 
786
794
#if defined(__SUBSURFACE__) && defined(__HAIR__)
787
795
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair
788
 
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
789
 
#include "kernel_bvh_traversal.h"
 
796
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
 
797
#include "kernel_bvh_subsurface.h"
790
798
#endif
791
799
 
792
800
#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
793
801
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
794
 
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_MOTION
795
 
#include "kernel_bvh_traversal.h"
 
802
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
 
803
#include "kernel_bvh_subsurface.h"
796
804
#endif
797
805
 
798
806
#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
799
807
#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair_motion
800
 
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_SUBSURFACE|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
801
 
#include "kernel_bvh_traversal.h"
802
 
#endif
803
 
 
804
 
 
 
808
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
 
809
#include "kernel_bvh_subsurface.h"
 
810
#endif
 
811
 
 
812
/* to work around titan bug when using arrays instead of textures */
 
813
#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
 
814
__device_inline
 
815
#else
 
816
__device_noinline
 
817
#endif
805
818
#ifdef __HAIR__ 
806
 
__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
 
819
bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
807
820
#else
808
 
__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
 
821
bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
809
822
#endif
810
823
{
811
824
#ifdef __OBJECT_MOTION__
843
856
#endif /* __KERNEL_CPU__ */
844
857
}
845
858
 
 
859
/* to work around titan bug when using arrays instead of textures */
846
860
#ifdef __SUBSURFACE__
847
 
__device_inline int scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, float subsurface_random)
 
861
#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
 
862
__device_inline
 
863
#else
 
864
__device_noinline
 
865
#endif
 
866
uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
848
867
{
849
868
#ifdef __OBJECT_MOTION__
850
869
        if(kernel_data.bvh.have_motion) {
851
870
#ifdef __HAIR__
852
871
                if(kernel_data.bvh.have_curves)
853
 
                        return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, subsurface_random);
 
872
                        return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
854
873
#endif /* __HAIR__ */
855
874
 
856
 
                return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, subsurface_random);
 
875
                return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
857
876
        }
858
877
#endif /* __OBJECT_MOTION__ */
859
878
 
860
879
#ifdef __HAIR__ 
861
880
        if(kernel_data.bvh.have_curves)
862
 
                return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, subsurface_random);
 
881
                return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, lcg_state, max_hits);
863
882
#endif /* __HAIR__ */
864
883
 
865
884
#ifdef __KERNEL_CPU__
866
885
 
867
886
#ifdef __INSTANCING__
868
887
        if(kernel_data.bvh.have_instancing)
869
 
                return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, subsurface_random);
 
888
                return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
870
889
#endif /* __INSTANCING__ */
871
890
 
872
 
        return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, subsurface_random);
 
891
        return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
873
892
#else /* __KERNEL_CPU__ */
874
893
 
875
894
#ifdef __INSTANCING__
876
 
        return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, subsurface_random);
 
895
        return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
877
896
#else
878
 
        return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, subsurface_random);
 
897
        return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
879
898
#endif /* __INSTANCING__ */
880
899
 
881
900
#endif /* __KERNEL_CPU__ */
980
999
#endif
981
1000
}
982
1001
 
 
1002
/* same as above, except that isect->t is assumed to be in object space for instancing */
 
1003
__device_inline float3 bvh_triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
 
1004
{
 
1005
        float3 P = ray->P;
 
1006
        float3 D = ray->D;
 
1007
        float t = isect->t;
 
1008
 
 
1009
#ifdef __INTERSECTION_REFINE__
 
1010
        if(isect->object != ~0) {
 
1011
#ifdef __OBJECT_MOTION__
 
1012
                Transform tfm = sd->ob_itfm;
 
1013
#else
 
1014
                Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
 
1015
#endif
 
1016
 
 
1017
                P = transform_point(&tfm, P);
 
1018
                D = transform_direction(&tfm, D);
 
1019
                D = normalize(D);
 
1020
        }
 
1021
 
 
1022
        P = P + D*t;
 
1023
 
 
1024
        float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
 
1025
        float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
 
1026
        float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
 
1027
        float rt = Oz * invDz;
 
1028
 
 
1029
        P = P + D*rt;
 
1030
 
 
1031
        if(isect->object != ~0) {
 
1032
#ifdef __OBJECT_MOTION__
 
1033
                Transform tfm = sd->ob_tfm;
 
1034
#else
 
1035
                Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
 
1036
#endif
 
1037
 
 
1038
                P = transform_point(&tfm, P);
 
1039
        }
 
1040
 
 
1041
        return P;
 
1042
#else
 
1043
        return P + D*t;
 
1044
#endif
 
1045
}
 
1046
 
983
1047
#ifdef __HAIR__
984
1048
 
985
1049
__device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
1009
1073
 
1010
1074
__device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float t)
1011
1075
{
1012
 
        int flag = kernel_data.curve_kernel_data.curveflags;
 
1076
        int flag = kernel_data.curve.curveflags;
1013
1077
        float3 P = ray->P;
1014
1078
        float3 D = ray->D;
1015
1079
 
1062
1126
                sd->v = 0.0f;
1063
1127
#endif
1064
1128
 
1065
 
                if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_RIBBONS)
 
1129
                if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)
1066
1130
                        sd->Ng = normalize(-(D - tg * (dot(tg,D))));
1067
1131
                else {
1068
1132
                        sd->Ng = normalize(P - p_curr);
1080
1144
#endif
1081
1145
 
1082
1146
                if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
1083
 
                        sd->Ng = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
 
1147
                        sd->Ng = -(D - tg * dot(tg,D));
1084
1148
                        sd->Ng = normalize(sd->Ng);
1085
 
                        if (flag & CURVE_KN_NORMALCORRECTION) {
1086
 
                                sd->Ng = sd->Ng - gd * tg;
1087
 
                                sd->Ng = normalize(sd->Ng);
1088
 
                        }
1089
1149
                }
1090
1150
                else {
1091
1151
                        sd->Ng = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
1098
1158
                sd->N = sd->Ng;
1099
1159
 
1100
1160
                if (flag & CURVE_KN_TANGENTGNORMAL && !(flag & CURVE_KN_TRUETANGENTGNORMAL)) {
1101
 
                        sd->N = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
 
1161
                        sd->N = -(D - tg * dot(tg,D));
1102
1162
                        sd->N = normalize(sd->N);
1103
 
                        if (flag & CURVE_KN_NORMALCORRECTION) {
1104
 
                                sd->N = sd->N - gd * tg;
1105
 
                                sd->N = normalize(sd->N);
1106
 
                        }
1107
1163
                }
1108
1164
                if (!(flag & CURVE_KN_TANGENTGNORMAL) && flag & CURVE_KN_TRUETANGENTGNORMAL) {
1109
1165
                        sd->N = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);