|
From: James W. <ja...@fr...> - 2008-10-10 02:30:41
|
Some 3D formats allow applying different materials to the front and back faces of materials, and I was thinking about how to do that with Quesa. Preferably, I'd want to do it without duplicating the geometry, to save memory. At first I thought that backface culling plus orientation styles would do the trick: Counterclockwise orientation + backfacing-remove means that we define the counterclockwise faces to the the front, and cull out the clockwise ones. Clockwise orientation + backfacing-remove means that we define the clockwise faces to the the front, and cull out the counterclockwise ones. However, we need to take the vertex normals into account. If the normals were created to face toward the counterclockwise face, then when rendering the clockwise face, we need to flip the normals. Currently, Quesa will only flip normals (OpenGL two-sided lighting) when it's not doing backface culling. What I'm considering is adding a new backfacing style, call it kQ3BackfacingStyleRemoveFront, which will cull out the front faces (where "front" respects the orientation style), but also use two-sided lighting. With this addition, one could render two faces with a structure like this: Group front attribute set backfacing style remove geometry Group back attribute set backfacing style remove-front another reference to the same geometry Does that make sense? -- James W. Walker, Innoventive Software LLC <http://www.frameforge3d.com/> |
|
From: Jose' C. <cru...@ce...> - 2008-10-10 10:44:25
|
Il giorno 10/ott/08, alle ore 04:30, James Walker ha scritto: > > Group > front attribute set > backfacing style remove > geometry > Group > back attribute set > backfacing style remove-front > another reference to the same geometry > > Does that make sense? it should work. this construct will be created automatically by the importer, right? Pax et Bonum # Dott. José Cruanyes Aguilar - C.E. Soft srl # Pzza. Firenze,4 MILANO - XX Settembre 10, CREMONA # 02,3923101 0372,460602 |
|
From: Roger H. <rog...@mi...> - 2008-10-10 14:08:03
|
On 10 Oct, 2008, at 03:30, James Walker wrote: > Some 3D formats allow applying different materials to the front and > back > faces of materials, Yes but why? Any real world material has thickness even if its only 1 Angstrom unit so there should be two surfaces with some separation. But of course that does not help when importing from a format which is plain stupid. As long it does not slow down the rest of Quesa then your solution sounds fine, I might even use it in my importers. Best regards, Roger. > and I was thinking about how to do that with Quesa. > Preferably, I'd want to do it without duplicating the geometry, to > save memory. At first I thought that backface culling plus > orientation > styles would do the trick: > > Counterclockwise orientation + backfacing-remove means that we define > the counterclockwise faces to the the front, and cull out the > clockwise > ones. Clockwise orientation + backfacing-remove means that we define > the clockwise faces to the the front, and cull out the > counterclockwise > ones. > > However, we need to take the vertex normals into account. If the > normals were created to face toward the counterclockwise face, then > when > rendering the clockwise face, we need to flip the normals. Currently, > Quesa will only flip normals (OpenGL two-sided lighting) when it's not > doing backface culling. > > What I'm considering is adding a new backfacing style, call it > kQ3BackfacingStyleRemoveFront, which will cull out the front faces > (where "front" respects the orientation style), but also use two-sided > lighting. With this addition, one could render two faces with a > structure like this: > > Group > front attribute set > backfacing style remove > geometry > Group > back attribute set > backfacing style remove-front > another reference to the same geometry > > Does that make sense? > -- > James W. Walker, Innoventive Software LLC > <http://www.frameforge3d.com/> > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Quesa-develop mailing list > Que...@li... > https://lists.sourceforge.net/lists/listinfo/quesa-develop |
|
From: Roger H. <rog...@mi...> - 2008-10-21 13:35:14
|
What do you all think on this. When certain tri-grids get turned into tri-meshes, they sometimes generate null triangles because two of the four corners of one of the grid quadrilateral are coincident. For instance the original QuickDraw3D sample code generated a sphere and a cone with Tri-grids and at the poles of the sphere and the point of the cone, this happened. Would it be worthwhile to not generate these null triangles, or should the tri-mesh constructor function filter them out or should we continue to filter them out every time we render or do processing of triangulated data such as when doing CSG calculations. Roger Holmes. |
|
From: James W. <ja...@fr...> - 2008-10-28 18:32:56
|
Roger Holmes wrote: > What do you all think on this. When certain tri-grids get turned into > tri-meshes, they sometimes generate null triangles because two of the > four corners of one of the grid quadrilateral are coincident. For > instance the original QuickDraw3D sample code generated a sphere and a > cone with Tri-grids and at the poles of the sphere and the point of > the cone, this happened. Would it be worthwhile to not generate these > null triangles, or should the tri-mesh constructor function filter > them out or should we continue to filter them out every time we render > or do processing of triangulated data such as when doing CSG > calculations. I don't have a strong opinion, but it might be reasonable to filter out empty triangles in e3geom_trigrid_cache_new. -- James W. Walker, Innoventive Software LLC <http://www.frameforge3d.com/> |
|
From: Roger H. <rog...@mi...> - 2008-10-30 14:35:16
|
On 28 Oct, 2008, at 18:32, James Walker wrote: >> What do you all think on this. When certain tri-grids get turned into >> tri-meshes, they sometimes generate null triangles because two of the >> four corners of one of the grid quadrilateral are coincident. For >> instance the original QuickDraw3D sample code generated a sphere >> and a >> cone with Tri-grids and at the poles of the sphere and the point of >> the cone, this happened. Would it be worthwhile to not generate these >> null triangles, or should the tri-mesh constructor function filter >> them out or should we continue to filter them out every time we >> render >> or do processing of triangulated data such as when doing CSG >> calculations. > > I don't have a strong opinion, but it might be reasonable to filter > out > empty triangles in e3geom_trigrid_cache_new. Good, that's what I meant by "the tri-mesh constructor function". I will look at that function when I get some spare time. |
|
From: Roger H. <rog...@mi...> - 2008-12-15 16:16:32
|
I have improved the spot light handling code in Quesa's RayShade renderer. Would anyone like to test and check in the changes? Before they did not seem to work so I lifted some code I wrote for the Microspot Renderer and it seems to work quite well now, though it may need optimisation some time. Roger Holmes. |
|
From: Roger H. <rog...@mi...> - 2009-03-19 21:04:56
Attachments:
smime.p7s
|
Firstly let me say I am using a one or two year old version of Quesa so its possible a suitable routine has been added since. I want to quickly scan through all the vertices of an object to see if they ALL have a diffuse colour attribute, which means that setting the objects own diffuse colour will have no effect, so the user option should be greyed out. I don't think there is any way of doing this on a geometry object so I have to split off each type of object. For a polygon there is a useful routine Q3Polygon_GetVertexAttributeSet, which takes the object, an index and an attribute set. Trouble is, I can't find a simple routine which tells me the maximum index. Of course I can get the TQ3PolygonData and read it from there, but not only is that slow, if I get that I can read the vertex array directly so don't need Q3Polygon_GetVertexAttributeSet. Am I missing something or is this just silly design? Roger Holmes |
|
From: James W. <ja...@fr...> - 2009-03-19 22:37:33
|
Roger Holmes wrote: > For a polygon there is a useful routine Q3Polygon_GetVertexAttributeSet, > which takes the object, an index and an attribute set. Trouble is, I > can't find a simple routine which tells me the maximum index. Of course > I can get the TQ3PolygonData and read it from there, but not only is > that slow, if I get that I can read the vertex array directly so don't > need Q3Polygon_GetVertexAttributeSet. Am I missing something or is this > just silly design? It does seem like a silly design (and the same could be said about PolyLine and Polyhedron). But it's not clear to me that Q3Polygon_GetData should be slower than calling Q3Polygon_GetVertexAttributeSet for every vertex. Have you profiled it? -- James W. Walker, Innoventive Software LLC <http://www.frameforge3d.com/> |
|
From: Roger H. <rog...@mi...> - 2009-03-20 12:45:16
|
On 19 Mar 2009, at 22:10, James Walker wrote: > Roger Holmes wrote: > >> For a polygon there is a useful routine >> Q3Polygon_GetVertexAttributeSet, >> which takes the object, an index and an attribute set. Trouble is, I >> can't find a simple routine which tells me the maximum index. Of >> course >> I can get the TQ3PolygonData and read it from there, but not only is >> that slow, if I get that I can read the vertex array directly so >> don't >> need Q3Polygon_GetVertexAttributeSet. Am I missing something or is >> this >> just silly design? > > It does seem like a silly design (and the same could be said about > PolyLine and Polyhedron). But it's not clear to me that > Q3Polygon_GetData should be slower than calling > Q3Polygon_GetVertexAttributeSet for every vertex. Have you profiled > it? No, it was just a gut feeling, and more to do with our wrapper classes than with Quesa itself. I will add routines in our wrappers to get the various count via GetData routine for each of the different geometries and probably all will then be OK. Thanks. |
|
From: Roger H. <rog...@mi...> - 2008-12-16 17:23:52
|
I have also fixed the problem with RayShade stretching images when drawn into non square windows if anyone's interested. Roger. |
|
From: Sauro A. <sag...@in...> - 2008-12-17 18:42:35
|
Well done Roger. Finally these 2 old RayShade bugs are fixxed, thank you. I'll try the new version asap. Sauro >I have also fixed the problem with RayShade stretching images when >drawn into non square windows if anyone's interested. > >Roger. > > >------------------------------------------------------------------------------ >SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. >The future of the web can't happen without you. Join us at MIX09 to help >pave the way to the Next Web now. Learn more and register at >http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ >_______________________________________________ >Quesa-develop mailing list >Que...@li... >https://lists.sourceforge.net/lists/listinfo/quesa-develop -- ----------------------------------------------------------------------------- _ ___ |_| __| Interstudio S.r.l. Tel + 39 0573 99291 Fax + 39 0573 992930 | |__ | Piazza Monteoliveto 6a http://www.interstudio.net |_____| I-51100 Pistoia Italy mailto:int...@in... ----------------------------------------------------------------------------- |
|
From: Roger H. <rog...@mi...> - 2008-12-18 13:41:21
|
Hi Sauro and all,
First the aspect ratio bug.
In file RT.cpp in RT_SetCamera,
at the end of the routine, change the whole if statement to:
if ( aspectRatioXToY <= 1.0 )
{
Camera.hfov = Q3Math_RadiansToDegrees ( minfov ) ;
Camera.vfov = Q3Math_RadiansToDegrees ( atan ( tan ( minfov *
0.5 ) / aspectRatioXToY ) * 2.0 ) ;
}
else
{
Camera.vfov = Q3Math_RadiansToDegrees ( minfov ) ;
Camera.hfov = Q3Math_RadiansToDegrees ( atan ( tan ( minfov *
0.5 ) * aspectRatioXToY ) * 2.0 ) ;
}
The code was very nearly right but Quesa's FieldOfView is the whole
angle from one side to the other but the original calculation assumed
it was the angle from the centre of the view to the outside. Basically
I just halve the input angle and then double the output value and
cleaned the code up a tiny bit.
I will send another email later about the spot lights.
Roger.
On 17 Dec, 2008, at 17:45, Sauro Agostini wrote:
> Well done Roger. Finally these 2 old RayShade bugs are fixxed, thank
> you.
>
> I'll try the new version asap.
>
> Sauro
>
>> I have also fixed the problem with RayShade stretching images when
>> drawn into non square windows if anyone's interested.
>>
>> Roger.
>>
>>
>> ------------------------------------------------------------------------------
>> SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas,
>> Nevada.
>> The future of the web can't happen without you. Join us at MIX09
>> to help
>> pave the way to the Next Web now. Learn more and register at
>> http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
>> _______________________________________________
>> Quesa-develop mailing list
>> Que...@li...
>> https://lists.sourceforge.net/lists/listinfo/quesa-develop
>
>
> --
> -----------------------------------------------------------------------------
> _ ___
> |_| __| Interstudio S.r.l. Tel + 39 0573 99291 Fax + 39
> 0573 992930
> | |__ | Piazza Monteoliveto 6a http://www.interstudio.net
> |_____| I-51100 Pistoia Italy mailto:int...@in...
> -----------------------------------------------------------------------------
>
> ------------------------------------------------------------------------------
> SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas,
> Nevada.
> The future of the web can't happen without you. Join us at MIX09 to
> help
> pave the way to the Next Web now. Learn more and register at
> http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
> _______________________________________________
> Quesa-develop mailing list
> Que...@li...
> https://lists.sourceforge.net/lists/listinfo/quesa-develop
|
|
From: Roger H. <rog...@mi...> - 2008-12-19 13:05:16
|
Hi,
To fix the problem with spot lights:
In LibLight/spot.h
replace the lines:
#define LightSpotCreate(c,f,t,p,i,o) LightCreate( \
(LightRef)SpotCreate(f,t,p,i,o), SpotMethods(), c)
typedef struct {
Vector pos, dir;
Float coef, radius, falloff;
} Spotlight;
extern Spotlight *
SpotCreate(Vector *from,Vector *to,Float coef,Float in,Float out);
with:
#define LightSpotCreate(c,f,t,i,o,at,fo) LightCreate( \
(LightRef)SpotCreate(f,t,i,o,at,fo), SpotMethods(), c)
typedef struct {
Vector pos, dir;
Float hotAngle ;
Float outerAngle ;
Float cosHotAngle ;
Float cosOuterAngle ;
int attenuation ;
int fallOff ;
} Spotlight;
extern Spotlight *
SpotCreate ( Vector* from , Vector* dir , Float hotAngle , Float
outerAngle , int attenuation , int fallOff ) ;
Then in LibLight/spot.cpp replace:
static Float rampup(Float left,Float right,Float at);
static Float SpotAtten(Spotlight *lp, Vector *dir);
Spotlight *
SpotCreate(
Vector *from,
Vector *to,
Float coef,
Float in,
Float out)
{
Spotlight *spot;
spot = (Spotlight *)share_malloc(sizeof(Spotlight));
spot->pos = *from;
VecSub(*to, *from, &spot->dir);
if (VecNormalize(&spot->dir) == 0. || in > out) {
RLerror(RL_ABORT,"Invalid spotlight specification.\n");
return (Spotlight *)NULL;
}
spot->coef = coef;
spot->radius = cos(deg2rad(in));
spot->falloff = cos(deg2rad(out));
return spot;
}
with:
static Float SpotAtten(Spotlight *lp, Vector *dir);
Spotlight *
SpotCreate(
Vector *from,
Vector *dir,
Float hotAngle,
Float outerAngle ,
int attenuation ,
int fallOff )
{
Spotlight *spot;
spot = (Spotlight *)share_malloc(sizeof(Spotlight));
spot->pos = *from;
spot->dir.x = dir->x ;
spot->dir.y = dir->y ;
spot->dir.z = dir->z ;
if (VecNormalize(&spot->dir) == 0. || hotAngle > outerAngle ) {
RLerror(RL_ABORT,"Invalid spotlight specification.\n");
return (Spotlight *)NULL;
}
spot->hotAngle = hotAngle ;
spot->outerAngle = outerAngle ;
spot->cosHotAngle = cos ( hotAngle ) ;
spot->cosOuterAngle = cos ( outerAngle ) ;
spot->attenuation = attenuation ;
spot->fallOff = fallOff ;
return spot;
}
and further down the same file replace:
/*
* Compute intensity of spotlight along 'dir'.
*/
static Float
SpotAtten(
Spotlight *lp,
Vector *dir)
{
Float costheta, atten;
costheta = -dotp(dir, &lp->dir);
/*
* Behind spotlight.
*/
if (costheta <= 0.)
return 0.;
/*
* Intensity is the product of costheta raised to lp->coef and
* a function that smoothly interpolates from 0 at
* costheta=lp->falloff to 1 at costheta=lp->radius.
*/
atten = pow(costheta, lp->coef);
if (lp->radius > 0.)
atten *= rampup(lp->falloff, lp->radius, costheta);
return atten;
}
/*
* Cubic interpolation between 0 at left and 1 at right, sampled at
'at'
* It is assumed that right >= left.
*/
Float
rampup(Float left,Float right,Float at)
{
if (at < left)
return 0.;
else if (at > right)
return 1.;
if (right == left)
return 0.;
at = (at - left) / (right - left);
return (3 - 2*at)*at*at;
}
with:
#define kQ3PiOver2 ((Float)
(3.1415926535898 / 2.0))
static const float eMinus1 = exp ( 1.0f ) - 1.0f ;
/*
* Compute intensity of spotlight along 'dir'.
*/
static Float
SpotAtten(
Spotlight *lp,
Vector *dir)
{
Float costheta, atten;
costheta = -dotp(dir, &lp->dir);
/*
* Behind spotlight.
*/
if (costheta <= 0.)
return 0.;
if ( costheta < lp->cosOuterAngle )
return 0.0 ;
atten = costheta ;
if (lp->cosHotAngle > 0.) // What is this all about ?
{
Float fallOffMultiplier = 1.0 ;
if ( lp->fallOff == 1 /*kQ3FallOffTypeLinear*/ )
{
if ( costheta < lp->cosHotAngle )
{
Float angle = acos ( costheta ) ;
fallOffMultiplier = ( lp->outerAngle - angle ) / ( lp->outerAngle
- lp->hotAngle ) ;
}
}
else
if ( lp->fallOff == 2/*kQ3FallOffTypeExponential*/ )
{
if ( costheta < lp->cosHotAngle )
{
Float angle = acos ( costheta ) ;
fallOffMultiplier = ( exp ( ( lp->outerAngle - angle ) / ( lp-
>outerAngle - lp->hotAngle ) ) - 1 ) / eMinus1 ;
}
}
else
if ( lp->fallOff == 3/*kQ3FallOffTypeCosine*/ )
{
if ( costheta < lp->cosHotAngle )
{
Float angle = acos ( costheta ) ;
fallOffMultiplier = cos ( ( angle - lp->hotAngle ) * kQ3PiOver2 /
( lp->outerAngle - lp->hotAngle ) ) ;
}
}
/*
This may be required some time but presently neither the attenuation
nor the world pixel position are available. Maybe it should go
somewhere else in the calculations
if ( lp->attenuation != kQ3AttenuationTypeNone )
{
switch ( lp->attenuation )
{
case kQ3AttenuationTypeInverseDistance :
{
fallOffMultiplier *= 1.0f / Distance ( pixelWorldPos - lp-
>pos ) ;
break ;
}
case kQ3AttenuationTypeInverseDistanceSquared :
{
fallOffMultiplier *= 1.0f / DistanceSquared ( pixelWorldPos -
lp->pos ) ;
break ;
}
}
}
*/
atten *= fallOffMultiplier ;
}
return atten;
}
Nearly there. In RT_Light.cpp, in subroutine RT_AddSpotLight replace:
theVector.x = -inDirection->x;
theVector.y = -inDirection->y;
theVector.z = -inDirection->z;
switch(inFallOffType)
{
case kQ3FallOffTypeNone:
theCoeff = 0.0f;
break;
case kQ3FallOffTypeLinear:
theCoeff = 1.0f;
break;
case kQ3FallOffTypeExponential:
theCoeff = 0.8f;
break;
case kQ3FallOffTypeCosine:
theCoeff = 2.0f;
break;
}
theLight = LightSpotCreate(&theColor,
&thePos,
&theVector,
theCoeff,
Q3Math_RadiansToDegrees(hotAngle),
Q3Math_RadiansToDegrees(outerAngle));
with:
theVector.x = inDirection->x;
theVector.y = inDirection->y;
theVector.z = inDirection->z;
theLight = LightSpotCreate(&theColor,
&thePos,
&theVector,
hotAngle ,
outerAngle ,
kQ3AttenuationTypeNone ,
inFallOffType ) ; // Use kQ3AttenuationTypeNone until we find we
need thee proper value
Thats it.
I tried including the file which defines kQ3FallOffTypeExponential etc
but had problems with multiply defined names, hence the slightly
questionable way I've used constants 1,2 and 3 in SpotAtten.
Roger.
|
|
From: Roger H. <rog...@mi...> - 2008-12-22 15:42:46
|
Hi Sauro, Could you also correct an error in the UV mapping. In RS_Texture.cpp please change the line: rsPrivate->uvTransform.value[1][1] *= -1.0f; to read: rsPrivate->uvTransform.value[0][1] *= -1.0f; rsPrivate->uvTransform.value[1][1] *= -1.0f; rsPrivate->uvTransform.value[2][1] *= -1.0f; in other words, copy and paste twice and change the first index to be 0,1 and 2 in the three cases. This fixes a problem with texture rotation direction and V offset. Roger. |
|
From: James W. W. <os...@jw...> - 2009-01-02 04:30:52
Attachments:
smime.p7s
|
For the benefit of any lurkers who aren't subscribed to the cvs commits mailing list: Roger's recent RayShade fixes have been committed. |