Files
OCCT/src/Visual3d/Visual3d_Light.cxx
2012-03-05 19:23:40 +04:00

519 lines
15 KiB
C++
Executable File

/***********************************************************************
FONCTION :
----------
File Visual3d_Light :
Declaration des variables specifiques aux sources lumineuses
REMARQUES:
----------
Une source lumineuse est definie par :
- son type
- sa couleur
- les facteurs d'attenuation (positionnelle et spot uniquement )
- son angle ( pour spot uniquement )
- sa concentration ( pour spot uniquement )
- sa direction ( directionnelle et spot uniquement )
- sa position ( positionnelle et spot uniquement )
Elle est active dans une vue, dans le contexte associe.
ATTENTION:
----------
- AngleCone est exprime en radian [Pex] alors que OpenGl travaille
en degres. Les limites pour Pex sont [0,PI] alors que pour OpenGl
ce sont [0,90].
- On utilise 2 facteurs d'attenuation avec Pex alors qu'OpenGl en utilise 3.
- Les facteurs d'attenuation sont limites entre [0.0,1.0] pour Pex alors
que pour OpenGl la limite est [0.0,n]
- La concentration varie entre [0.,1.0] pour Pex et [0,128] pour OpenGl.
HISTORIQUE DES MODIFICATIONS :
--------------------------------
01-03-92 : NW,JPB,CAL ; Creation.
19-12-96 : FMN ; PRO6793:
Modification des bornes pour AngleCone [0,PI/2]
Ajout commentaires dans le cdl.
Ajout tests sur les bornes.
10-07-97 : PCT
Ajout des headlights
23-02-98 : FMN ; Remplacement PI par Standard_PI
************************************************************************/
/*----------------------------------------------------------------------*/
/*
* Includes
*/
#include <Visual3d_Light.ixx>
#include <Graphic3d_GraphicDriver.hxx>
/*----------------------------------------------------------------------*/
Visual3d_Light::Visual3d_Light ():
MyType (Visual3d_TOLS_AMBIENT) {
MyCLight.WsId = -1;
MyCLight.ViewId = 0; /* not used */
MyCLight.LightType = int (MyType);
MyCLight.Headlight = 0;
Quantity_Color White (Quantity_NOC_WHITE);
MyCLight.Color.r = float (White.Red ());
MyCLight.Color.g = float (White.Green ());
MyCLight.Color.b = float (White.Blue ());
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
}
/*----------------------------------------------------------------------*/
Visual3d_Light::Visual3d_Light (const Quantity_Color& Color):
MyType (Visual3d_TOLS_AMBIENT) {
MyCLight.WsId = -1;
MyCLight.ViewId = 0; /* not used */
MyCLight.LightType = int (MyType);
MyCLight.Headlight = 0;
MyCLight.Color.r = float (Color.Red ());
MyCLight.Color.g = float (Color.Green ());
MyCLight.Color.b = float (Color.Blue ());
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
}
/*----------------------------------------------------------------------*/
Visual3d_Light::Visual3d_Light(const Quantity_Color& Color,const Graphic3d_Vector& Direction,const Standard_Boolean Headlight): MyType (Visual3d_TOLS_DIRECTIONAL) {
if (Direction.LengthZero ())
Visual3d_LightDefinitionError::Raise
("Bad value for LightDirection");
MyCLight.WsId = -1;
MyCLight.ViewId = 0; /* not used */
MyCLight.LightType = int (MyType);
MyCLight.Headlight = Headlight? 1:0;
Standard_Real Norme, X, Y, Z;
Color.Values (X, Y, Z, Quantity_TOC_RGB);
MyCLight.Color.r = float (X);
MyCLight.Color.g = float (Y);
MyCLight.Color.b = float (Z);
Direction.Coord (X, Y, Z);
Norme = Sqrt (X*X+Y*Y+Z*Z);
// Direction.LengthZero () == Standard_False
MyCLight.Direction.x = float (X/Norme);
MyCLight.Direction.y = float (Y/Norme);
MyCLight.Direction.z = float (Z/Norme);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
}
/*----------------------------------------------------------------------*/
Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Standard_Real Fact1, const Standard_Real Fact2):
MyType (Visual3d_TOLS_POSITIONAL) {
if ( (Fact1 == 0.0) && (Fact2 == 0.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (Fact1 < 0.0) && (Fact1 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (Fact2 < 0.0) && (Fact2 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
MyCLight.WsId = -1;
MyCLight.ViewId = 0; /* not used */
MyCLight.LightType = int (MyType);
MyCLight.Headlight = 0;
MyCLight.Color.r = float (Color.Red ());
MyCLight.Color.g = float (Color.Green ());
MyCLight.Color.b = float (Color.Blue ());
MyCLight.Position.x = float (Position.X ());
MyCLight.Position.y = float (Position.Y ());
MyCLight.Position.z = float (Position.Z ());
MyCLight.Attenuation[0] = float (Fact1);
MyCLight.Attenuation[1] = float (Fact2);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
}
/*----------------------------------------------------------------------*/
Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Graphic3d_Vector& Direction, const Standard_Real Concentration, const Standard_Real Fact1, const Standard_Real Fact2, const Standard_Real AngleCone):
MyType (Visual3d_TOLS_SPOT) {
if (Direction.LengthZero ())
Visual3d_LightDefinitionError::Raise
("Bad value for LightDirection");
if ( (Concentration < 0.0) || (Concentration > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightConcentration");
if ( (Fact1 == 0.0) && (Fact2 == 0.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (Fact1 < 0.0) && (Fact1 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (Fact2 < 0.0) && (Fact2 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if (Visual3d_Light::IsValid (AngleCone)) {
MyCLight.WsId = -1;
MyCLight.ViewId = 0; /* not used */
MyCLight.LightType = int (MyType);
MyCLight.Headlight = 0;
Standard_Real X, Y, Z;
Color.Values (X, Y, Z, Quantity_TOC_RGB);
MyCLight.Color.r = float (X);
MyCLight.Color.g = float (Y);
MyCLight.Color.b = float (Z);
Position.Coord (X, Y, Z);
MyCLight.Position.x = float (X);
MyCLight.Position.y = float (Y);
MyCLight.Position.z = float (Z);
Direction.Coord (X, Y, Z);
MyCLight.Direction.x = float (X);
MyCLight.Direction.y = float (Y);
MyCLight.Direction.z = float (Z);
MyCLight.Concentration = float (Concentration);
MyCLight.Attenuation[0] = float (Fact1);
MyCLight.Attenuation[1] = float (Fact2);
MyCLight.Angle = float (AngleCone);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
}
else
Visual3d_LightDefinitionError::Raise
("Bad value for LightAngle");
}
/*----------------------------------------------------------------------*/
Quantity_Color Visual3d_Light::Color () const {
Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
Standard_Real (MyCLight.Color.g),
Standard_Real (MyCLight.Color.b),
Quantity_TOC_RGB);
return (AColor);
}
/*----------------------------------------------------------------------*/
Visual3d_TypeOfLightSource Visual3d_Light::LightType () const {
return (MyType);
}
/*----------------------------------------------------------------------*/
Standard_Boolean Visual3d_Light::Headlight () const {
return MyCLight.Headlight==0? Standard_False:Standard_True;
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::Values (Quantity_Color& Color) const {
Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
Standard_Real (MyCLight.Color.g),
Standard_Real (MyCLight.Color.b),
Quantity_TOC_RGB);
if (MyType == Visual3d_TOLS_AMBIENT)
Color = AColor;
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_AMBIENT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vector& Direction) const {
Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
Standard_Real (MyCLight.Color.g),
Standard_Real (MyCLight.Color.b),
Quantity_TOC_RGB);
Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x),
Standard_Real (MyCLight.Direction.y),
Standard_Real (MyCLight.Direction.z));
if (MyType == Visual3d_TOLS_DIRECTIONAL) {
Color = AColor;
Direction = ADirection;
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_DIRECTIONAL");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Standard_Real& Fact1, Standard_Real& Fact2) const {
Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
Standard_Real (MyCLight.Color.g),
Standard_Real (MyCLight.Color.b),
Quantity_TOC_RGB);
Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x),
Standard_Real (MyCLight.Position.y),
Standard_Real (MyCLight.Position.z));
if (MyType == Visual3d_TOLS_POSITIONAL) {
Color = AColor;
Position = APosition;
Fact1 = Standard_Real (MyCLight.Attenuation[0]);
Fact2 = Standard_Real (MyCLight.Attenuation[1]);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_POSITIONAL");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Graphic3d_Vector& Direction, Standard_Real& Concentration, Standard_Real& Fact1, Standard_Real& Fact2, Standard_Real& AngleCone) const {
Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
Standard_Real (MyCLight.Color.g),
Standard_Real (MyCLight.Color.b),
Quantity_TOC_RGB);
Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x),
Standard_Real (MyCLight.Position.y),
Standard_Real (MyCLight.Position.z));
Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x),
Standard_Real (MyCLight.Direction.y),
Standard_Real (MyCLight.Direction.z));
if (MyType == Visual3d_TOLS_SPOT) {
Color = AColor;
Position = APosition;
Direction = ADirection;
Concentration = Standard_Real (MyCLight.Concentration);
Fact1 = Standard_Real (MyCLight.Attenuation[0]);
Fact2 = Standard_Real (MyCLight.Attenuation[1]);
AngleCone = Standard_Real (MyCLight.Angle);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetAngle (const Standard_Real AngleCone) {
if (! Visual3d_Light::IsValid (AngleCone))
Visual3d_LightDefinitionError::Raise
("Bad value for LightAngle");
if (MyType == Visual3d_TOLS_SPOT) {
MyCLight.Angle = float (AngleCone);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetAttenuation1 (const Standard_Real Fact1) {
if ( (Fact1 < 0.0) && (Fact1 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
(MyType == Visual3d_TOLS_SPOT) ) {
MyCLight.Attenuation[0] = float (Fact1);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetAttenuation2 (const Standard_Real Fact2) {
if ( (Fact2 < 0.0) && (Fact2 > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightAttenuation");
if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
(MyType == Visual3d_TOLS_SPOT) ) {
MyCLight.Attenuation[1] = float (Fact2);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetColor (const Quantity_Color& Color) {
MyCLight.Color.r = float (Color.Red ());
MyCLight.Color.g = float (Color.Green ());
MyCLight.Color.b = float (Color.Blue ());
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetConcentration (const Standard_Real Concentration) {
if ( (Concentration < 0.0) || (Concentration > 1.0) )
Visual3d_LightDefinitionError::Raise
("Bad value for LightConcentration");
if (MyType == Visual3d_TOLS_SPOT) {
MyCLight.Concentration = float (Concentration);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetDirection (const Graphic3d_Vector& Direction) {
if (Direction.LengthZero ())
Visual3d_LightDefinitionError::Raise
("Bad value for LightDirection");
if ( (MyType == Visual3d_TOLS_DIRECTIONAL) ||
(MyType == Visual3d_TOLS_SPOT) ) {
Standard_Real Norme, X, Y, Z;
Direction.Coord (X, Y, Z);
Norme = Sqrt (X*X+Y*Y+Z*Z);
// Direction.LengthZero () == Standard_False
MyCLight.Direction.x = float (X/Norme);
MyCLight.Direction.y = float (Y/Norme);
MyCLight.Direction.z = float (Z/Norme);
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
void Visual3d_Light::SetPosition (const Graphic3d_Vertex& Position) {
if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
(MyType == Visual3d_TOLS_SPOT) ) {
MyCLight.Position.x = float (Position.X ());
MyCLight.Position.y = float (Position.Y ());
MyCLight.Position.z = float (Position.Z ());
MyCLight.LightId =
Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
}
else Visual3d_LightDefinitionError::Raise
("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
}
/*----------------------------------------------------------------------*/
Standard_Integer Visual3d_Light::Limit () {
// Old method, replaced by GraphicDriver::InquireLightLimit ()
return 0;
}
/*----------------------------------------------------------------------*/
Standard_Integer Visual3d_Light::Identification () const {
return (Standard_Integer (MyCLight.LightId));
}
/*----------------------------------------------------------------------*/
Standard_Boolean Visual3d_Light::IsValid (const Standard_Real AAngle) {
return ( (AAngle < Standard_PI) && (AAngle >= 0.0) );
}
/*----------------------------------------------------------------------*/