Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F64327392
m_direct.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, May 26, 03:39
Size
4 KB
Mime Type
text/x-c
Expires
Tue, May 28, 03:39 (2 d)
Engine
blob
Format
Raw Data
Handle
17884741
Attached To
R10977 RADIANCE Photon Map
m_direct.c
View Options
#ifndef lint
static
const
char
RCSid
[]
=
"$Id: m_direct.c,v 2.16 2018/11/13 19:58:33 greg Exp $"
;
#endif
/*
* Routines for light-redirecting materials and
* their associated virtual light sources
*/
#include "copyright.h"
#include "ray.h"
#include "otypes.h"
#include "rtotypes.h"
#include "source.h"
#include "func.h"
/*
* The arguments for MAT_DIRECT1 are:
*
* 5+ coef1 dx1 dy1 dz1 funcfile transform..
* 0
* n A1 A2 .. An
*
* The arguments for MAT_DIRECT2 are:
*
* 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
* 0
* n A1 A2 .. An
*/
static
int
redirect
(
OBJREC
*
m
,
RAY
*
r
,
int
n
);
static
int
dir_proj
(
MAT4
pm
,
OBJREC
*
o
,
SRCREC
*
s
,
int
n
);
VSMATERIAL
direct1_vs
=
{
dir_proj
,
1
};
VSMATERIAL
direct2_vs
=
{
dir_proj
,
2
};
#define getdfunc(m) ( (m)->otype == MAT_DIRECT1 ? \
getfunc(m, 4, 0xf, 1) : \
getfunc(m, 8, 0xff, 1) )
int
m_direct
(
/* shade redirected ray */
OBJREC
*
m
,
RAY
*
r
)
{
/* check if source ray */
if
(
r
->
rsrc
>=
0
&&
source
[
r
->
rsrc
].
so
!=
r
->
ro
)
return
(
1
);
/* got the wrong guy */
/* compute first projection */
if
(
m
->
otype
==
MAT_DIRECT1
||
(
r
->
rsrc
<
0
||
source
[
r
->
rsrc
].
sa
.
sv
.
pn
==
0
))
redirect
(
m
,
r
,
0
);
/* compute second projection */
if
(
m
->
otype
==
MAT_DIRECT2
&&
(
r
->
rsrc
<
0
||
source
[
r
->
rsrc
].
sa
.
sv
.
pn
==
1
))
redirect
(
m
,
r
,
1
);
return
(
1
);
}
static
int
redirect
(
/* compute n'th ray redirection */
OBJREC
*
m
,
RAY
*
r
,
int
n
)
{
MFUNC
*
mf
;
EPNODE
**
va
;
FVECT
nsdir
;
RAY
nr
;
double
coef
;
int
j
;
/* set up function */
mf
=
getdfunc
(
m
);
setfunc
(
m
,
r
);
/* assign direction variable */
if
(
r
->
rsrc
>=
0
)
{
SRCREC
*
sp
=
source
+
source
[
r
->
rsrc
].
sa
.
sv
.
sn
;
if
(
sp
->
sflags
&
SDISTANT
)
VCOPY
(
nsdir
,
sp
->
sloc
);
else
{
for
(
j
=
0
;
j
<
3
;
j
++
)
nsdir
[
j
]
=
sp
->
sloc
[
j
]
-
r
->
rop
[
j
];
normalize
(
nsdir
);
}
multv3
(
nsdir
,
nsdir
,
funcxf
.
xfm
);
varset
(
"DxA"
,
'='
,
nsdir
[
0
]
/
funcxf
.
sca
);
varset
(
"DyA"
,
'='
,
nsdir
[
1
]
/
funcxf
.
sca
);
varset
(
"DzA"
,
'='
,
nsdir
[
2
]
/
funcxf
.
sca
);
}
else
{
varset
(
"DxA"
,
'='
,
0.0
);
varset
(
"DyA"
,
'='
,
0.0
);
varset
(
"DzA"
,
'='
,
0.0
);
}
/* compute coefficient */
errno
=
0
;
va
=
mf
->
ep
+
4
*
n
;
coef
=
evalue
(
va
[
0
]);
if
((
errno
==
EDOM
)
|
(
errno
==
ERANGE
))
goto
computerr
;
setcolor
(
nr
.
rcoef
,
coef
,
coef
,
coef
);
if
(
rayorigin
(
&
nr
,
TRANS
,
r
,
nr
.
rcoef
)
<
0
)
return
(
0
);
va
++
;
/* compute direction */
for
(
j
=
0
;
j
<
3
;
j
++
)
{
nr
.
rdir
[
j
]
=
evalue
(
va
[
j
]);
if
(
errno
==
EDOM
||
errno
==
ERANGE
)
goto
computerr
;
}
if
(
mf
->
fxp
!=
&
unitxf
)
multv3
(
nr
.
rdir
,
nr
.
rdir
,
mf
->
fxp
->
xfm
);
if
(
r
->
rox
!=
NULL
)
multv3
(
nr
.
rdir
,
nr
.
rdir
,
r
->
rox
->
f
.
xfm
);
if
(
normalize
(
nr
.
rdir
)
==
0.0
)
goto
computerr
;
/* compute value */
if
(
r
->
rsrc
>=
0
)
nr
.
rsrc
=
source
[
r
->
rsrc
].
sa
.
sv
.
sn
;
rayvalue
(
&
nr
);
multcolor
(
nr
.
rcol
,
nr
.
rcoef
);
addcolor
(
r
->
rcol
,
nr
.
rcol
);
if
(
r
->
ro
!=
NULL
&&
isflat
(
r
->
ro
->
otype
))
r
->
rxt
=
r
->
rot
+
raydistance
(
&
nr
);
return
(
1
);
computerr:
objerror
(
m
,
WARNING
,
"compute error"
);
return
(
-
1
);
}
static
int
dir_proj
(
/* compute a director's projection */
MAT4
pm
,
OBJREC
*
o
,
SRCREC
*
s
,
int
n
)
{
RAY
tr
;
OBJREC
*
m
;
MFUNC
*
mf
;
EPNODE
**
va
;
FVECT
cent
,
newdir
,
nv
,
h
;
double
coef
,
olddot
,
newdot
,
od
;
int
i
,
j
;
/* initialize test ray */
getmaxdisk
(
cent
,
o
);
if
(
s
->
sflags
&
SDISTANT
)
for
(
i
=
0
;
i
<
3
;
i
++
)
{
tr
.
rdir
[
i
]
=
-
s
->
sloc
[
i
];
tr
.
rorg
[
i
]
=
cent
[
i
]
-
tr
.
rdir
[
i
];
}
else
{
for
(
i
=
0
;
i
<
3
;
i
++
)
{
tr
.
rdir
[
i
]
=
cent
[
i
]
-
s
->
sloc
[
i
];
tr
.
rorg
[
i
]
=
s
->
sloc
[
i
];
}
if
(
normalize
(
tr
.
rdir
)
==
0.0
)
return
(
0
);
/* at source! */
}
od
=
getplaneq
(
nv
,
o
);
olddot
=
DOT
(
tr
.
rdir
,
nv
);
if
(
olddot
<=
FTINY
&&
olddot
>=
-
FTINY
)
return
(
0
);
/* old dir parallels plane */
tr
.
rmax
=
0.0
;
rayorigin
(
&
tr
,
PRIMARY
,
NULL
,
NULL
);
if
(
!
(
*
ofun
[
o
->
otype
].
funp
)(
o
,
&
tr
))
return
(
0
);
/* no intersection! */
/* compute redirection */
m
=
vsmaterial
(
o
);
mf
=
getdfunc
(
m
);
setfunc
(
m
,
&
tr
);
varset
(
"DxA"
,
'='
,
0.0
);
varset
(
"DyA"
,
'='
,
0.0
);
varset
(
"DzA"
,
'='
,
0.0
);
errno
=
0
;
va
=
mf
->
ep
+
4
*
n
;
coef
=
evalue
(
va
[
0
]);
if
(
errno
==
EDOM
||
errno
==
ERANGE
)
goto
computerr
;
if
(
coef
<=
FTINY
)
return
(
0
);
/* insignificant */
va
++
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
newdir
[
i
]
=
evalue
(
va
[
i
]);
if
(
errno
==
EDOM
||
errno
==
ERANGE
)
goto
computerr
;
}
if
(
mf
->
fxp
!=
&
unitxf
)
multv3
(
newdir
,
newdir
,
mf
->
fxp
->
xfm
);
/* normalization unnecessary */
newdot
=
DOT
(
newdir
,
nv
);
if
(
newdot
<=
FTINY
&&
newdot
>=
-
FTINY
)
return
(
0
);
/* new dir parallels plane */
/* everything OK -- compute shear */
for
(
i
=
0
;
i
<
3
;
i
++
)
h
[
i
]
=
newdir
[
i
]
/
newdot
-
tr
.
rdir
[
i
]
/
olddot
;
setident4
(
pm
);
for
(
j
=
0
;
j
<
3
;
j
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
pm
[
i
][
j
]
+=
nv
[
i
]
*
h
[
j
];
pm
[
3
][
j
]
=
-
od
*
h
[
j
];
}
if
((
newdot
>
0.0
)
^
(
olddot
>
0.0
))
/* add mirroring */
for
(
j
=
0
;
j
<
3
;
j
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
pm
[
i
][
j
]
-=
2.
*
nv
[
i
]
*
nv
[
j
];
pm
[
3
][
j
]
+=
2.
*
od
*
nv
[
j
];
}
return
(
1
);
computerr:
objerror
(
m
,
WARNING
,
"projection compute error"
);
return
(
0
);
}
Event Timeline
Log In to Comment