Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / Scene Compositor sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 :
27 :
28 : #include "nodes_stacks.h"
29 :
30 : #ifndef GPAC_DISABLE_VRML
31 :
32 : #ifndef GPAC_DISABLE_3D
33 :
34 : #include "visual_manager.h"
35 :
36 :
37 759 : static void TraverseSpotLight(GF_Node *n, void *rs, Bool is_destroy)
38 : {
39 : M_SpotLight *sl = (M_SpotLight *)n;
40 : GF_TraverseState *tr_state = (GF_TraverseState *) rs;
41 :
42 759 : if (is_destroy) {
43 1 : Bool *vis = (Bool*)gf_node_get_private(n);
44 1 : gf_free(vis);
45 1 : return;
46 : }
47 758 : if (!sl->on) {
48 0 : visual_3d_has_inactive_light(tr_state->visual);
49 0 : return;
50 : }
51 :
52 : /*store local bounds for culling*/
53 758 : if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
54 : GF_BBox b;
55 : SFVec3f size;
56 151 : Bool *visible = (Bool*)gf_node_get_private(n);
57 151 : size.x = size.y = size.z = sl->radius;
58 151 : gf_vec_add(b.max_edge, sl->location, size);
59 151 : gf_vec_diff(b.min_edge, sl->location, size);
60 151 : gf_bbox_refresh(&b);
61 151 : *visible = visual_3d_node_cull(tr_state, &b, GF_FALSE);
62 : /*if visible, disable culling on our parent branch - this is not very efficient but
63 : we only store one bound per grouping node, and we don't want the lights to interfere with it*/
64 151 : if (*visible) tr_state->disable_cull = GF_TRUE;
65 : return;
66 : }
67 607 : else if (tr_state->traversing_mode == TRAVERSE_LIGHTING) {
68 151 : Bool *visible = (Bool*)gf_node_get_private(n);
69 151 : if (*visible) {
70 151 : visual_3d_add_spot_light(tr_state->visual, sl->ambientIntensity, sl->attenuation, sl->beamWidth,
71 : sl->color, sl->cutOffAngle, sl->direction, sl->intensity, sl->location, &tr_state->model_matrix);
72 : } else {
73 0 : visual_3d_has_inactive_light(tr_state->visual);
74 : }
75 : }
76 : }
77 :
78 1 : void compositor_init_spot_light(GF_Compositor *compositor, GF_Node *node)
79 : {
80 1 : Bool *vis = (Bool*)gf_malloc(sizeof(Bool));
81 1 : *vis = GF_FALSE;
82 1 : gf_node_set_private(node, vis);
83 : /*no need for a stck*/
84 1 : gf_node_set_callback_function(node, TraverseSpotLight);
85 1 : }
86 :
87 759 : static void TraversePointLight(GF_Node *n, void *rs, Bool is_destroy)
88 : {
89 : M_PointLight *pl = (M_PointLight *)n;
90 : GF_TraverseState *tr_state = (GF_TraverseState *) rs;
91 :
92 759 : if (is_destroy) {
93 1 : Bool *vis = (Bool*)gf_node_get_private(n);
94 1 : gf_free(vis);
95 1 : return;
96 : }
97 758 : if (!pl->on) {
98 0 : visual_3d_has_inactive_light(tr_state->visual);
99 0 : return;
100 : }
101 :
102 : /*store local bounds for culling*/
103 758 : if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
104 : SFVec3f size;
105 : GF_BBox b;
106 151 : Bool *visible = (Bool*)gf_node_get_private(n);
107 151 : size.x = size.y = size.z = pl->radius;
108 151 : gf_vec_add(b.max_edge, pl->location, size);
109 151 : gf_vec_diff(b.min_edge, pl->location, size);
110 151 : gf_bbox_refresh(&b);
111 151 : *visible = visual_3d_node_cull(tr_state, &b, GF_FALSE);
112 : /*if visible, disable culling on our parent branch*/
113 151 : if (*visible) tr_state->disable_cull = GF_TRUE;
114 : return;
115 : }
116 607 : else if (tr_state->traversing_mode == TRAVERSE_LIGHTING) {
117 151 : Bool *visible = (Bool*)gf_node_get_private(n);
118 151 : if (*visible) {
119 151 : visual_3d_add_point_light(tr_state->visual, pl->ambientIntensity, pl->attenuation, pl->color,
120 : pl->intensity, pl->location, &tr_state->model_matrix);
121 : } else {
122 0 : visual_3d_has_inactive_light(tr_state->visual);
123 : }
124 : }
125 : }
126 :
127 1 : void compositor_init_point_light(GF_Compositor *compositor, GF_Node *node)
128 : {
129 1 : Bool *vis = (Bool*)gf_malloc(sizeof(Bool));
130 1 : *vis = GF_FALSE;
131 1 : gf_node_set_private(node, vis);
132 : /*no need for a stck*/
133 1 : gf_node_set_callback_function(node, TraversePointLight);
134 1 : }
135 :
136 :
137 5099 : static void TraverseDirectionalLight(GF_Node *n, void *rs, Bool is_destroy)
138 : {
139 5099 : Bool *stack = (Bool*)gf_node_get_private(n);
140 : M_DirectionalLight *dl = (M_DirectionalLight *)n;
141 : GF_TraverseState *tr_state = (GF_TraverseState *) rs;
142 :
143 5099 : if (is_destroy) {
144 8 : gf_free(stack);
145 8 : return;
146 : }
147 5091 : if (tr_state->switched_off || !dl->on) {
148 0 : visual_3d_has_inactive_light(tr_state->visual);
149 0 : return;
150 : }
151 :
152 : /*1- DL only lights the parent group, no need for culling it*/
153 : /*DL is set dynamically while traversing, the only mode that interest us is draw*/
154 5091 : if (tr_state->traversing_mode) return;
155 :
156 1487 : if (tr_state->local_light_on) {
157 1487 : *stack = visual_3d_add_directional_light(tr_state->visual, dl->ambientIntensity, dl->color, dl->intensity, dl->direction, &tr_state->model_matrix);
158 : } else {
159 0 : if (*stack) visual_3d_remove_last_light(tr_state->visual);
160 0 : *stack = GF_FALSE;
161 0 : visual_3d_has_inactive_light(tr_state->visual);
162 : }
163 : }
164 :
165 8 : void compositor_init_directional_light(GF_Compositor *compositor, GF_Node *node)
166 : {
167 8 : Bool *stack = (Bool*)gf_malloc(sizeof(Bool));
168 8 : *stack = GF_FALSE;
169 8 : gf_node_set_private(node, stack);
170 8 : gf_node_set_callback_function(node, TraverseDirectionalLight);
171 8 : }
172 :
173 : #endif /*GPAC_DISABLE_3D*/
174 :
175 : #endif /*GPAC_DISABLE_VRML*/
|