Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Skinny3DSources ƒ/Lights.c
// file Lights.c |
#include <Types.h> |
#include "SkinnyMain.h" |
#include "Lights.h" |
// #include "ValueControls.h" |
// local prototypes |
static VccPtr LightDataToVcc (TQ3LightData lightData); |
static VccPtr DirectLightDataToVcc(TQ3DirectionalLightData drLightData); |
static VccPtr PointLightDataToVcc (TQ3PointLightData ptLightData); |
static VccPtr SpotLightDataToVcc (TQ3SpotLightData spLightData); |
static void AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData); |
static void VccToLightData (VccPtr vcc, TQ3LightData *lightData); |
static void VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData); |
static void VccToPointLightData (VccPtr vcc, TQ3PointLightData *ptLightData); |
static void VccToSpotLightData (VccPtr vcc, TQ3SpotLightData *spLightData); |
static void GetStdLightDataValues(VccPtr vcc, TQ3LightData *lightData); |
static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType); |
extern Rect gContrlRect; |
// -------------------------------------------------------------------- |
TQ3GroupObject MakeLights(void) |
{ |
TQ3GroupPosition groupPosition; |
TQ3GroupObject lightGroup; |
TQ3LightData lightData; |
TQ3PointLightData pointLightData; |
TQ3DirectionalLightData directLightData; |
TQ3SpotLightData spotLightData; |
TQ3LightObject ambientLight, pointLight, fillLight, spotLight; |
TQ3Point3D pointLocation = { -10.0, 0.0, 10.0 }; |
TQ3Vector3D fillDirection = { -5.0, 0.0, 10.0 }; |
TQ3Point3D spotLocation = { -10.0, 10.0, 10.0 }; |
TQ3Vector3D spotDirection = { 10.0, -10.0, -10.0 }; |
TQ3ColorRGB WhiteLight = { 1.0, 1.0, 1.0 }; |
// Set up light data for ambient light. This light data will be used for point and fill |
// light also. |
lightData.isOn = kQ3True; |
lightData.color = WhiteLight; |
lightData.brightness = .2; |
// Create ambient light. |
ambientLight = Q3AmbientLight_New(&lightData); |
if ( ambientLight == nil ) goto bail; |
// Create point light. |
lightData.brightness = 1.0; |
pointLightData.lightData = lightData; |
pointLightData.castsShadows = kQ3False; |
pointLightData.attenuation = kQ3AttenuationTypeNone; |
pointLightData.location = pointLocation; |
pointLight = Q3PointLight_New(&pointLightData); |
if ( pointLight == nil ) goto bail; |
// Create fill light. |
lightData.brightness = .8; |
directLightData.lightData = lightData; |
directLightData.castsShadows = kQ3False; |
directLightData.direction = fillDirection; |
fillLight = Q3DirectionalLight_New(&directLightData); |
if ( fillLight == nil ) goto bail; |
// Create spot light. |
lightData.brightness = .4; |
spotLightData.lightData = lightData; |
spotLightData.castsShadows = kQ3False; |
spotLightData.attenuation = kQ3AttenuationTypeNone; |
spotLightData.location = spotLocation; |
spotLightData.direction = spotDirection; |
spotLightData.hotAngle = 0.2; |
spotLightData.outerAngle = 0.4; |
spotLightData.fallOff = kQ3FallOffTypeLinear; |
spotLight = Q3SpotLight_New(&spotLightData); |
if ( spotLight == nil ) goto bail; |
// Create light group and add each of the lights into the group. |
lightGroup = Q3LightGroup_New(); |
if ( lightGroup == nil ) goto bail; |
groupPosition = Q3Group_AddObject(lightGroup, ambientLight); |
if ( groupPosition == 0 ) goto bail; |
groupPosition = Q3Group_AddObject(lightGroup, pointLight); |
if ( groupPosition == 0 ) goto bail; |
groupPosition = Q3Group_AddObject(lightGroup, fillLight); |
if ( groupPosition == 0 ) goto bail; |
groupPosition = Q3Group_AddObject(lightGroup, spotLight); |
if ( groupPosition == 0 ) goto bail; |
// Done! |
return ( lightGroup ); |
bail: // If any of the above failed, then return nothing! |
return ( nil ); |
} |
// -------------------------------------------------------------------- |
static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType) |
{ |
TQ3Status status; |
TQ3Object object; |
TQ3LightObject light; |
TQ3GroupPosition position; |
Boolean found = false; |
status = Q3Group_GetFirstPosition(lightGroup, &position); |
if (status != kQ3Success) |
return NULL; |
do { |
status = Q3Group_GetPositionObject(lightGroup, position, &object); |
if (object == NULL) |
return NULL; |
light = (TQ3LightObject)object; |
found = (Q3Light_GetType(light) == lType); |
status = Q3Group_GetNextPosition(lightGroup, &position); |
} while ((!found) && (position != NULL)); |
if (found) |
return light; |
else |
return NULL; |
} |
// -------------------------------------------------------------------- |
VccPtr LightToVCC(TQ3GroupObject lightGroup, long selector) |
{ |
TQ3LightObject light; |
TQ3Status status; |
TQ3ObjectType lType; |
TQ3LightData lightData; |
TQ3DirectionalLightData drLightData; |
TQ3PointLightData ptLightData; |
TQ3SpotLightData spLightData; |
switch (selector) { |
case iAmbient: lType = kQ3LightTypeAmbient; break; |
case iDirectional: lType = kQ3LightTypeDirectional; break; |
case iPoint: lType = kQ3LightTypePoint; break; |
case iSpot: lType = kQ3LightTypeSpot; break; |
default: return nil; |
} |
light = FindLight(lightGroup, lType); |
switch (selector) { |
case iAmbient: |
status = Q3AmbientLight_GetData(light, &lightData); |
return LightDataToVcc(lightData); |
break; |
case iDirectional: |
status = Q3DirectionalLight_GetData(light, &drLightData); |
return DirectLightDataToVcc(drLightData); |
break; |
case iPoint: |
status = Q3PointLight_GetData(light, &ptLightData); |
return PointLightDataToVcc(ptLightData); |
break; |
case iSpot: |
status = Q3SpotLight_GetData(light, &spLightData); |
return SpotLightDataToVcc(spLightData); |
break; |
default: |
return nil; |
} |
} |
#define cBasicLines 7 |
// -------------------------------------------------------------------- |
static VccPtr LightDataToVcc(TQ3LightData lightData) |
{ |
VccPtr vcc; |
vcc = NewVCluster((long)kQ3LightTypeAmbient, "\pAmbientLightData", cBasicLines, &gContrlRect); |
if (vcc == nil) return nil; |
AddStdLightDataValues(vcc, lightData); |
return vcc; |
} |
// -------------------------------------------------------------------- |
static VccPtr DirectLightDataToVcc(TQ3DirectionalLightData drLightData) |
{ |
VccPtr vcc; |
vcc = NewVCluster((long)kQ3LightTypeDirectional, "\pDirectionalLightData", |
cBasicLines + 4, &gContrlRect); |
if (vcc == nil) return nil; |
AddStdLightDataValues(vcc, drLightData.lightData); |
AddValueCtl(vcc, "\pcastsShadows", drLightData.castsShadows, 0.0, 1.0, 1.0); // [7] |
AddValueCtl(vcc, "\pdirection.x", drLightData.direction.x, -30.0, 30.0, 3.0); |
AddValueCtl(vcc, "\pdirection.y", drLightData.direction.y, -30.0, 30.0, 3.0); |
AddValueCtl(vcc, "\pdirection.z", drLightData.direction.z, -30.0, 30.0, 3.0); |
return vcc; |
} |
// -------------------------------------------------------------------- |
static VccPtr PointLightDataToVcc(TQ3PointLightData ptLightData) |
{ |
VccPtr vcc; |
vcc = NewVCluster((long)kQ3LightTypePoint, "\pPointLightData", cBasicLines + 6, &gContrlRect); |
if (vcc == nil) return nil; |
AddStdLightDataValues(vcc, ptLightData.lightData); |
AddValueCtl(vcc, "\pcastsShadows", ptLightData.castsShadows, 0.0, 1.0, 1.0); // [7] |
AddValueCtl(vcc, "\pattenuation", ptLightData.attenuation, 0.0, 2.0, 1.0); |
AddSeparator(vcc); |
AddValueCtl(vcc, "\plocation.x", ptLightData.location.x, -30.0, 30.0, 3.0); // [10] |
AddValueCtl(vcc, "\plocation.y", ptLightData.location.y, -30.0, 30.0, 3.0); |
AddValueCtl(vcc, "\plocation.z", ptLightData.location.z, -30.0, 30.0, 3.0); |
return vcc; |
} |
// -------------------------------------------------------------------- |
static VccPtr SpotLightDataToVcc(TQ3SpotLightData spLightData) |
{ |
VccPtr vcc; |
vcc = NewVCluster((long)kQ3LightTypeSpot, "\pSpotLightData", cBasicLines + 14, &gContrlRect); |
if (vcc == nil) return nil; |
AddStdLightDataValues(vcc, spLightData.lightData); |
AddValueCtl(vcc, "\pcastsShadows", spLightData.castsShadows, 0.0, 1.0, 1.0); // [7] |
AddValueCtl(vcc, "\pattenuation", spLightData.attenuation, 0.0, 2.0, 1.0); |
AddSeparator(vcc); |
AddValueCtl(vcc, "\plocation.x", spLightData.location.x, -30.0, 30.0, 3.0); // [10] |
AddValueCtl(vcc, "\plocation.y", spLightData.location.y, -30.0, 30.0, 3.0); |
AddValueCtl(vcc, "\plocation.z", spLightData.location.z, -30.0, 30.0, 3.0); |
AddSeparator(vcc); |
AddValueCtl(vcc, "\pdirection.x", spLightData.direction.x, -30.0, 30.0, 3.0); // [14] |
AddValueCtl(vcc, "\pdirection.y", spLightData.direction.y, -30.0, 30.0, 3.0); |
AddValueCtl(vcc, "\pdirection.z", spLightData.direction.z, -30.0, 30.0, 3.0); |
AddSeparator(vcc); |
AddValueCtl(vcc, "\photAngle", spLightData.hotAngle, 0.05, 1.0, 0.05); // [18] |
AddValueCtl(vcc, "\pouterAngle", spLightData.outerAngle, 0.1, 2.0, 0.1); |
AddValueCtl(vcc, "\pfallOff", spLightData.fallOff, 0.0, 3.0, 1.0); |
return vcc; |
} |
// -------------------------------------------------------------------- |
static void AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData) |
{ |
AddValueCtl(vcc, "\pisOn", lightData.isOn, 0.0, 1.0, 1.0); // [0] |
AddValueCtl(vcc, "\pbrightness",lightData.brightness, 0.0, 1.0, 0.1); |
AddSeparator(vcc); |
AddValueCtl(vcc, "\pcolor.r", lightData.color.r, 0.0, 1.0, 0.1); // [3] |
AddValueCtl(vcc, "\pcolor.g", lightData.color.g, 0.0, 1.0, 0.1); |
AddValueCtl(vcc, "\pcolor.b", lightData.color.b, 0.0, 1.0, 0.1); |
AddSeparator(vcc); // cBasicLines = 7 |
} |
// -------------------------------------------------------------------- |
void VCCtoLight(VccPtr vcc, TQ3GroupObject lightGroup) |
{ |
TQ3LightData lightData; |
TQ3DirectionalLightData drLightData; |
TQ3PointLightData ptLightData; |
TQ3SpotLightData spLightData; |
TQ3Status status; |
TQ3LightObject light; |
TQ3ObjectType lType; |
lType = (TQ3ObjectType)GetIdTag(vcc); |
light = FindLight(lightGroup, lType); |
if (light == NULL) |
return; |
switch (lType) { |
case kQ3LightTypeAmbient: |
VccToLightData(vcc, &lightData); |
status = Q3AmbientLight_SetData(light, &lightData); |
break; |
case kQ3LightTypeDirectional: |
VccToDirectLightData(vcc, &drLightData); |
status = Q3DirectionalLight_SetData(light, &drLightData); |
break; |
case kQ3LightTypePoint: |
VccToPointLightData(vcc, &ptLightData); |
status = Q3PointLight_SetData(light, &ptLightData); |
break; |
case kQ3LightTypeSpot: |
VccToSpotLightData(vcc, &spLightData); |
status = Q3SpotLight_SetData(light, &spLightData); |
break; |
} |
} |
// -------------------------------------------------------------------- |
static void VccToLightData(VccPtr vcc, TQ3LightData *lightData) |
{ |
lightData->isOn = (GetCurrentValue(vcc, 0) == 1.0); |
lightData->brightness = GetCurrentValue(vcc, 1); |
lightData->color.r = GetCurrentValue(vcc, 3); |
lightData->color.g = GetCurrentValue(vcc, 4); |
lightData->color.b = GetCurrentValue(vcc, 5); |
} |
// -------------------------------------------------------------------- |
static void VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData) |
{ |
VccToLightData(vcc, &drLightData->lightData); |
drLightData->castsShadows = (GetCurrentValue(vcc, 7) == 1.0); |
drLightData->direction.x = GetCurrentValue(vcc, 8); |
drLightData->direction.y = GetCurrentValue(vcc, 9); |
drLightData->direction.z = GetCurrentValue(vcc, 10); |
} |
// -------------------------------------------------------------------- |
static void VccToPointLightData (VccPtr vcc, TQ3PointLightData *ptLightData) |
{ |
VccToLightData(vcc, &ptLightData->lightData); |
ptLightData->castsShadows = (GetCurrentValue(vcc, 7) == 1.0); |
ptLightData->attenuation = GetCurrentValue(vcc, 8); // 0, 1, 2 |
ptLightData->location.x = GetCurrentValue(vcc, 10); |
ptLightData->location.y = GetCurrentValue(vcc, 11); |
ptLightData->location.z = GetCurrentValue(vcc, 12); |
} |
// -------------------------------------------------------------------- |
static void VccToSpotLightData (VccPtr vcc, TQ3SpotLightData *spLightData) |
{ |
VccToLightData(vcc, &spLightData->lightData); |
spLightData->castsShadows = (GetCurrentValue(vcc, 7) == 1.0); |
spLightData->attenuation = GetCurrentValue(vcc, 8); // 0, 1, 2 |
spLightData->location.x = GetCurrentValue(vcc, 10); |
spLightData->location.y = GetCurrentValue(vcc, 11); |
spLightData->location.z = GetCurrentValue(vcc, 12); |
spLightData->direction.x = GetCurrentValue(vcc, 14); |
spLightData->direction.y = GetCurrentValue(vcc, 15); |
spLightData->direction.z = GetCurrentValue(vcc, 16); |
spLightData->hotAngle = GetCurrentValue(vcc, 18); |
spLightData->outerAngle = GetCurrentValue(vcc, 19); |
spLightData->fallOff = GetCurrentValue(vcc, 20); // 0, 1, 2, 3 |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14