Issue with timer in .lsl (Linden Scripting Language) - linden-scripting-language

Have a problem with the script below written in .lsl (Linden Scripting Language)
It is designed to let one renter A (first renter) to rent the space and can rent out the space for renter B (second renter)
The 1st problem is that for renter B the time the space is rented for ends to fast. Applys from state active
And 2nd problem is renter B should pay at least 25% of the total price renter A sets at the first time, but after the init price is payed renter B cannot pay any more even the total amount payed should be what renter A sets.
//varibles for renter A
// elapsedRentalTime = .0;
// rentalTime = 0;
// rentalName = "<No body>";
// rentalUUID = NULL_KEY;
// rentalSetPrice = 0;
// rentalSetTime = .0;
//varibles for renter B
// endName = "<No Body>";
// endUUID = NULL_KEY;
// endRentalTime = .0;
// endRentalPayd = 0;
Hope somone can help with this issue. also sorry for any typeos there may be : )
//cant pay after the int 25% of amt / renter time for renter B ends to fast
integer chan;
list butPrice = ["0","1","2","3","4","5","6","7","8","9","Set price","Reset price"];
list butTime = ["Hour+","Hour-","Day+","Day-","Week+","Week-","Set time","Reset time"];
integer lis1;
key owner;
integer rentPrice;
float rentTime;
float dialogTime = .0;
key rentalUUID = NULL_KEY;
string rentalName = "<No body>";
float rentalTime;
float elapsedRentalTime;
integer rentalSetPrice;
float rentalSetTime;
key endUUID = NULL_KEY;
string endName = "<No body>";
float endRentalTime;
integer endRentalPayd;
float ONE_WEEK = 604800.0;
float ONE_DAY = 86400.0;
float ONE_HOUR = 3600.0;
string getTimeString(integer time){
string str;
integer week;
integer days;
integer hours;
integer minutes;
integer seconds;
week = llRound(time / 604800);
time = time % 604800;
days = (time / 86400);
time = time % 86400;
hours = (time / 3600);
time = time % 3600;
minutes = time / 60;
time = time % 60;
seconds = time;
if(week)
str += (string)week + " weeks, ";
if(days)
str += (string)days + " days, ";
if(hours)
str += (string)hours + " hours, ";
if(minutes)
str += (string)minutes + " minutes, ";
if(seconds)
str += (string)seconds + " seconds, ";
if(str != "")
str = llDeleteSubString(str,-2,-1);
if(str == "")
str = "Not Set!";
return str;
}
Dialog2(key i,string str,list but){
dialogTime += 15.;
llListenRemove(lis1);
lis1 = llListen(chan,"","","");
llDialog(i,str,but,chan);
}
EndRental(){
llSetTimerEvent(.0);
elapsedRentalTime = .0;
rentalTime = 0;
rentalName = "<No body>";
rentalUUID = NULL_KEY;
rentalSetPrice = 0;
rentalSetTime = .0;
endName = "<No Body>";
endUUID = NULL_KEY;
endRentalTime = .0;
endRentalPayd = 0;
llMessageLinked(LINK_THIS, 1, "Free space|Rate L$"+(string)rentPrice+" \ week|Max: "+getTimeString((integer)rentTime), llGetKey());
}
integer subPrice;
integer Config1(key i,string m){
if(m == "Set price"){
Dialog2(i,"Price: "+(string)subPrice+"L$",["Ok"]);
return subPrice;
}
else if(m == "Reset price")
subPrice = 0;
else
subPrice = (integer)((string)subPrice+m);
Dialog2(i,"(Set price)\n"+(string)subPrice+"L$",butPrice);
return subPrice;
}
integer subTime;
integer Config2(key i,string m){
if(m == "Hour+")
subTime += 3600;
else if(m == "Hour-")
subTime -= 3600;
else if(m == "Day+")
subTime += 86400;
else if(m == "Day-")
subTime -= 86400;
else if(m == "Week+")
subTime += 604800;
else if(m == "Week-")
subTime -= 604800;
else if(m == "Set time"){
Dialog2(i,"Time: "+(string)getTimeString(subTime),["Ok"]);
return subTime;
}
else if(m == "Reset time")
subTime = 0;
Dialog2(i,"(Set time)\n"+getTimeString((integer)subTime),butTime);
return subTime;
}
TextInfo(){
llWhisper(0,"Price: L$ "+(string)rentPrice+" / week\nMax time: "+getTimeString((integer)rentTime)+"\n---------------------\nRenter: "+rentalName+"\nEnd user: "+endName+
"\n---------------------\nPrice: L$ "+(string)rentalSetPrice+"\nTime: "+getTimeString((integer)rentalSetTime));
}
DisplayInfo(){
llMessageLinked(LINK_THIS, 1, "COST: "+(string)rentalSetPrice+"|PAID: "+(string)endRentalPayd+"|BUYER: "+endName, llGetKey());
}
default{
touch_end(integer e){
if(llDetectedKey(0) == owner){
subTime = subPrice = 0;
if(dialogTime == .0)
llSetTimerEvent(5.);
Dialog2(owner,"(Menu)",["Price","Time","Info","Activet"]);
}
}
listen(integer c,string n,key i,string m){
if(i == owner){
if(m == "Info")
TextInfo();
else if(m == "Activet"){
llMessageLinked(LINK_THIS, 1, "Free space|Rate L$"+(string)rentPrice+" \ week|Max: "+getTimeString((integer)rentTime), llGetKey());
llSetTimerEvent(.0);
state active;
}
else if(~llListFindList(butPrice,[m]) || m == "Price")
rentPrice = Config1(i,m);
else if(~llListFindList(butTime,[m]) || m == "Time")
rentTime = (float)Config2(i,m);
}
}
timer(){
float elapsedTime = llGetTime();
llResetTime();
if((dialogTime -= elapsedTime) <= .0){
dialogTime = .0;
llListenRemove(lis1);
llSetTimerEvent(.0);
}
}
run_time_permissions(integer p){
if(!(p & PERMISSION_DEBIT)){
llOwnerSay("Debit perm not set! Reseting script...");
llResetScript();
}
}
state_entry(){
owner = llGetOwner();
llRequestPermissions(owner,PERMISSION_DEBIT);
chan = (integer)llGetSubString("0x"+(string)llGetKey(),-1,-5);
}
on_rez(integer r){
llResetScript();
}
}
state active{
state_entry(){
}
touch_end(integer e){
key id = llDetectedKey(0);
if(id == rentalUUID){
Dialog2(rentalUUID,"(Renter Menu)",["Price","Time","End rental","Info"]);
}
else if(id == owner)
Dialog2(owner,"(Owner menu)",["No refund","Refund","Info"]);
else
Dialog2(id,"(Menu)",["Info"]);
}
listen(integer c,string n,key i,string m){
if(m == "Info")
TextInfo();
else if(i == rentalUUID){
if(m == "End rental")
Dialog2(rentalUUID,"(Menu)\nEnd rental with no refun?",["No ref!","Cancel"]);
else if(m == "No ref!")
EndRental();
else if(~llListFindList(butPrice,[m]) || m == "Price")
rentalSetPrice = Config1(i,m);
else if(~llListFindList(butTime,[m]) || m == "Time")
rentalSetTime = (float)Config2(i,m);
if(rentalSetTime+elapsedRentalTime > rentTime+120.){
rentalSetTime = 0;
llInstantMessage(rentalUUID,"Time set is greater then max rental time allowd");
}
DisplayInfo();
}
else if(i == owner){
if(m == "No refund")
Dialog2(owner,"(Owner menu)\nEnd rental with no refund?",["No ref!","Cancel"]);
else if(m == "Refund")
Dialog2(owner,"(Owner menu)\nEnd rental with refund?",["Ref!","Cancel"]);
else if(m == "No ref!")
EndRental();
else if(m == "Ref!"){
integer amt = (integer)(rentalTime * rentPrice / ONE_WEEK);
if(amt)
llGiveMoney(rentalUUID,amt);
EndRental();
}
}
}
timer(){
float elapsedTime = llGetTime();
llResetTime();
rentalTime -= elapsedTime;
elapsedRentalTime += elapsedTime;
endRentalTime -= elapsedTime;
dialogTime -= elapsedTime;
if(rentalTime <= .0 && rentalUUID != NULL_KEY){
llInstantMessage(rentalUUID,"Your rental time at "+llGetRegionName()+" has now ended.");
EndRental();
}
if(endRentalTime <= .0 && endUUID != NULL_KEY){
llInstantMessage(endUUID,"Your rental time at "+llGetRegionName()+" has now ended.");
endName = "<No Body>";
endUUID = NULL_KEY;
endRentalTime = .0;
endRentalPayd = 0;
DisplayInfo();
}
if(dialogTime <= .0){
dialogTime = .0;
llListenRemove(lis1);
}
}
money(key i,integer amt){
float sum;
sum = ONE_WEEK * amt / rentPrice;
if(i == rentalUUID && sum + rentalTime + elapsedRentalTime <= rentTime){
rentalTime += sum;
llInstantMessage(rentalUUID,"You have refiled for "+getTimeString((integer)sum)+"\nand your total time is "+getTimeString((integer)sum));
}
else if(rentalUUID == NULL_KEY && sum <= rentTime){
rentalUUID = i;
rentalName = llKey2Name(rentalUUID);
rentalTime = sum;
llResetTime();
llInstantMessage(rentalUUID,"Your time left is "+getTimeString((integer)sum));
llSetTimerEvent(30.);
}
else if(i == endUUID && endRentalPayd+amt <= rentalSetPrice){
endRentalTime += rentalSetTime * amt / rentalSetPrice;
endRentalPayd += amt;
llGiveMoney(rentalUUID,amt);
llInstantMessage(endUUID,"Your time left is "+getTimeString((integer)endRentalTime));
}
else if(endUUID == NULL_KEY && amt >= rentalSetPrice*25/100 && amt <= rentalSetPrice && rentalUUID != NULL_KEY){
endUUID = i;
endName = llKey2Name(endUUID);
endRentalTime = rentalSetTime * amt / rentalSetPrice;
endRentalPayd = amt;
llGiveMoney(rentalUUID,amt);
llInstantMessage(endUUID,"Your time left is "+getTimeString((integer)endRentalTime));
}
else
llGiveMoney(i,amt);
DisplayInfo();
}
}

Recode to use LSL wiki / llGetUnixTime
this gives the code a easy to use set point in time to work from.
integer rental_expires = 0;
integer number_of_days_per_payment = 7;
integer secs_per_day = 86400; // ((60 * 60)*24)
add_time_to_rental()
{
integer time_to_add = (secs_per_day*number_of_days_per_payment);
if(rental_expires == 0)
{
rental_expires = llGetUnixTime() + time_to_add;
}
else
{
rental_expires = rental_expires + time_to_add;
}
}
to get when their rental expires
Unix2DateTime is a bit long winded
string timeleft()
{
integer secs_left = rental_expires - llGetUnixTime();
if(secs_left > 0)
{
integer mins_left = llFloor(secs_left / 60);
integer hours_left = llFloor(mins_left / 60);
integer days_left = llFloor(hours_left / 24);
integer weeks_left = llFloor(days_left / 7);
// correct the values
if(weeks_left > 0) days_left = days_left - (weeks_left*7);
if(days_left > 0) hours_left = hours_left - (days_left*24);
if(hours_left > 0) mins_left = mins_left - (hours_left*60);
return ""+(string)weeks_left+"weeks, "+(string)days_left+"days, "+(string)hours_left+"hours and "+(string)mins_left+"mins";
}
else return "Expired";
}
now you can have a timer event that runs once every 60secs to check if a rental has expired
if(llGetUnixTime() > rental_expires) llOwnerSay("Rental has expired");
once all of that is in place and working it should be alot easyer for you to add your other code to deal with the 2nd renter.

Related

if statement doesn't work on a triangle type function

I'm a complete newbie, so please excuse me.
I tried using online compiler but they unresponsive, and I get no return value (or return 0 for whatever I enter)
I tried to write a function that check if triangle is right, isosceles or both, and return 1,2,3 respectively, all other cases should return 0.
int main() {
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1==90 || angle2==90 || angleSum==90) {
/*if it is also an isosceles --->*/
if (angle2==45 || angle1==45) {
return 3;
}
return 1;
}
/*check if it only a isosceles*/
if (angle1==(180-angle2)/2 ||
angle2== (180-angle1)/2 ||
angle1==angle2) {
return 2;
}
return 0;
}
TriangleType(110, 111);
}
First, don't try to use nested functions in C. Pulling that function out of main.
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1==90 || angle2==90 || angleSum==90) {
/*if it is also an isosceles --->*/
if (angle2==45 || angle1==45) {
return 3;
}
return 1;
}
/*check if it only a isosceles*/
if (angle1==(180-angle2)/2 ||
angle2== (180-angle1)/2 ||
angle1==angle2) {
return 2;
}
return 0;
}
int main() {
TriangleType(110, 111);
}
Second, this doesn't do anything with the return value from the function, so of course you see no output.
int main(void) {
switch (TriangleType(110, 111)) {
case 1:
printf("Right triangle\n");
break;
case 2:
printf("Isosceles triangle\n");
break;
case 3:
printf("Both types\n");
break;
default:
printf("None of the above\n");
}
return 0;
}
Code is functionally wrong
Even after re-organizing and moving the nested function, code attempts to be clever and not perform simple tests.
if (angle1 == (180 - angle2) / 2 || angle2 == (180 - angle1) / 2 || angle1 == angle2) fails in cases like TriangleType(45,89) --> 2 as (180 - angle2) / 2 rounds down. angle1 * 2 == (180 - angle2) would make more sense.
TriangleType(90, 90), where the 3rd angle is 0, returns 0. That is asymmetric. TriangleType(0, 90), TriangleType(90, 0) do not return 0.
TriangleType(0, 0) returns 2. I would expect that to return 0, a rejected triangle.
Below is a test harness for OP to use and test TriangleType().
#include <stdio.h>
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1 == 90 || angle2 == 90 || angleSum == 90) {
/*if it is also an isosceles --->*/
if (angle2 == 45 || angle1 == 45) {
return 3;
}
return 1;
}
/*check if it only a isosceles */
if (angle1 == (180 - angle2) / 2 || angle2 == (180 - angle1) / 2
|| angle1 == angle2) {
return 2;
}
return 0;
}
int my_TriangleType(unsigned angle1, unsigned angle2) {
unsigned angle3 = 180 - angle1 - angle2;
if (angle1 >= 180 || angle2 >= 180 || angle3 >= 180) {
return 0;
}
if (angle1 == 0 || angle2 == 0 || angle3 == 0) {
return 0;
}
int retval = angle1 == 90 || angle2 == 90 || angle3 == 90 ? 1 : 0;
if (angle1 == angle2 || angle2 == angle3 || angle3 == angle1)
retval += 2;
return retval;
}
#include <string.h>
#define MAX_LIMIT 127
int main() {
printf("score:%d my_score:%d\n", TriangleType(45,89), my_TriangleType(45,89));
int error_count = 0;
int flags[4][4] = {0};
for (unsigned angle1 = 0; angle1 <= 181; angle1++) {
for (unsigned angle2 = 0; angle2 <= 181; angle2++) {
int score = TriangleType(angle1, angle2);
int my_score = my_TriangleType(angle1, angle2);
if (score != my_score) {
error_count++;
if (flags[score][my_score] == 0) {
flags[score][my_score] = 1;
printf("%3d angle1:%2u angle2:%2u score:%d my_score:%d\n", //
error_count, angle1, angle2, score, my_score);
}
}
}
}
printf("total errors:%d\n", error_count);
return 0;
}
Output:
score:2 my_score:0
1 angle1: 0 angle2: 0 score:2 my_score:0
2 angle1: 0 angle2:90 score:1 my_score:0
total errors:181
another_TriangleType() could be made that is more efficient than my_TriangleType(), yet it would needed to functionally match.
Well your questions is lacking some information, but I assume you got as inputs of your program, two angles.
THe fisrt thing we need to think is:
If you got a right triangle, than there is one of those values equals 90 degrees, instead the sum of them must be 90.
On the other hand, if you got an isosceles triangle you should have 2 equal values, instead you must have the 180 deg - sum of both angles should result in one of those two.
Let's try to code this out:
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define RIGHT 0x01
#define ISOSCELES 0x02
#define BOTH 0x03
// If you got a right triangle, than there is one of those values equals 90 degrees, instead the sum of them must be 90.
int bIsRightTriangle(int iAngDeg1, int iAngDeg2){
if ( iAngDeg1 == 90 || iAngDeg2 == 90 )
return TRUE;
if ( (iAngDeg1 + iAngDeg2) == 90 )
return TRUE;
return FALSE;
}
// On the other hand, if you got an isosceles triangle you should have 2 equal values,
// instead you must have the 180 deg - sum of both angles should result in one of those two.
int bIs_IsoscelesTriangle(int iAngDeg1, int iAngDeg2){
int iAngDeg3 = 180 - iAngDeg1 + iAngDeg2;
if ( iAngDeg1 == iAngDeg2 )
return TRUE;
if ( (iAngDeg3 == iAngDeg1) || (iAngDeg3 == iAngDeg2) )
return TRUE;
return FALSE;
}
int iGetTriangleTypeByAngles(int iAngDeg1, int iAngDeg2){
int iReturnType = 0;
iReturnType = bIsRightTriangle(iAngDeg1, iAngDeg2) ? (iReturnType | RIGHT) : iReturnType;
iReturnType = bIs_IsoscelesTriangle(iAngDeg1, iAngDeg2) ? (iReturnType | ISOSCELES) : iReturnType;
return iReturnType;
}
int main(int argc, char *argv[]){
if ( argc < 3 ){
return -1;
}
// In case you want an output
// printf("%d\n", iGetTriangleTypeByAngles(atoi(argv[1]), atoi(argv[2])));
return iGetTriangleTypeByAngles(atoi(argv[1]), atoi(argv[2]));
}

I want to make a parking fee program by using visual studio

int min1, min2, won;
printf("parking minutes(분)? ");
scanf("%d", &min1);
min2 = (min1 - 30) % 10;
if (min1 <= 39)
won = 2000;
else {
if (min2 = 0)
won = 2000 + 1000 * (min1 - 30) % 10;
else
won = 2000 + 1000 * (min1 - min2 - 20) % 10;
}
printf("parking fee: %d", won);
The conditions of this program
until 30min, 2000won
after 30min, 1000won per 10min
max 25000won per a day
parking minutes cannot be over than 24 hours
I thought that '%' means remainder so I write like that but when I input 52, the results say 5200! I want to make result to be 5000. And I want to know what to do for condition 3 and 4. What can I do? Should I use 'for' and 'sum'?
Let's program the steps in the same order as the assignment:
int min1, min2, won;
printf("parking minutes(분)? ");
if (scanf("%d", &min1) != 1) {
printf("invalid input\n");
return 1; // invalid input.
}
won = 2000; // 1. until 30min, 2000won, minimum price
if (min1 > 30) {
// 2. after 30min, 1000won per 10min
min2 = min1 - 30; // minutes after 30
// add 1000won for every slice or 10min or portion thereof
won += ((min2 + 9) % 10) * 1000;
// 3. max 25000won per a day
if (won > 25000)
won = 25000;
}
// 4. parking minutes cannot be over than 24 hours
if (min1 > 24 * 60) {
// reject request
printf("parking time exceeds 24 hours\n");
} else {
printf("parking fee: %d\n", won);
}
The problem is with the condition of your inner if in else block.
if(min2 = 0)
One equal sign is assignment operator, you have to use == for equality check.
if(min2 == 0)

Ray Box Intersection in C

I am trying to make a method to calculate a ray box intersection in C. Most of the procedures I googled show methods that return bools (if there is or there isn't an intersection). However, I need a method that can return a tuple (I know there are no tuples in C, but I made a struct to represent it). Specifically, I need the values of tmin and tmax, even though they are negative, and assigning them a negative value if the value does not exist. How should I manage the returns of this to work properly? The code I produced in C is based on the code displayed in this page: https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/. The actual implementation of the code in my program is as follows:
RectMinMax* Intersection(BoundingBox* b, Ray* r) {
RectMinMax* TMinMax = malloc(sizeof(RectMinMax));
float tmin = -INFINITY, tmax = INFINITY;
if (ray_get_direction(r).X != 0) {
float t1 = (b->x - ray_get_origin(r).X) / ray_get_direction(r).X;
float t2 = ((b->x + b->length) - ray_get_origin(r).X)/ ray_get_direction(r).X;
tmin = fmaxf(tmin, fminf(t1, t2));
tmax = fminf(tmax, fmaxf(t1, t2));
}
else if (ray_get_origin(r).X <= b->x || ray_get_origin(r).X >= (b->x + b->length)) {
TMinMax->min = -55;
TMinMax->max = -55;
return TMinMax;
}
if (ray_get_direction(r).Y != 0) {
float t1 = (b->y - ray_get_origin(r).Y) / ray_get_direction(r).Y;
float t2 = ((b->y + b->width) - ray_get_origin(r).Y)/ ray_get_direction(r).Y;
tmin = fmaxf(tmin, fminf(t1, t2));
tmax = fminf(tmax, fmaxf(t1, t2));
}
else if (ray_get_origin(r).Y <= b->y || ray_get_origin(r).Y >= (b->y + b->width)) {
TMinMax->min = -55;
TMinMax->max = -55;
return TMinMax;
}
if (ray_get_direction(r).Z != 0) {
float t1 = (b->z - ray_get_origin(r).Z) / ray_get_direction(r).Z;
float t2 = ((b->z + b->height) - ray_get_origin(r).Z)/ ray_get_direction(r).Z;
tmin = fmaxf(tmin, fminf(t1, t2));
tmax = fminf(tmax, fmaxf(t1, t2));
}
else if (ray_get_origin(r).Z <= b->z || ray_get_origin(r).Z >= (b->z + b->height)) {
TMinMax->min = -55;
TMinMax->max = -55;
return TMinMax;
}
if (tmax > tmin && tmax > 0) {
TMinMax->min = tmin;
TMinMax->max = tmax;
return TMinMax;
}
else {
TMinMax->min = -55;
TMinMax->max = -55;
return TMinMax;
}
}
RectMinMax is just a struct with to attributes max and min. In the code I used -55 to represent the "return false" cases of the code in the link. I understand I am leaving out cases in which tmax is positive and tmin negative, for example, but I do not know how to fix it.

Time game (hours, minutes, seconds)

first thanks watching. i tried to take an input (hour, minute, second, duration (seconds) )
and convert all to a total hour of arrival.
i got a problem when i enter this numbers : "23 59 59 10801".
what i am expecting to get is "arrival time - > 3 0 0 "
but actually i get nothing.
(every other positive number works just fine...)
thank for help, sorry if my code is a total mess.
:)
int h = 0, m = 0, s = 0, time = 0, ih = 0, im = 0, is = 0;
printf("please enter 4 digits\n");
scanf("%d %d %d %d", &h, &m, &s, &time);
if ((((h<=23)&&(h>0)) && ((m<=59) && (m>0)) && ((s<=59) && (s>0))) && (time > 0))
{
// hour loop
while (time >= 3600) {
++ih;
time = (time - 3600);
// minute loop
while ((time < 3600) && (time != 0)) {
++im;
time = (time - 60);
// second loop
while ((time <= 60) && (time != 0)) {
++is;
time = (time - 1);
}
}
}
h = (h + ih);
m = (m + im);
s = (s + is);
if (h >= 24) {
h = ((h * 0) + ih-1);
}
if (m = 60) {
m = (m * 0);
++h;
}
if (s = 60) {
s = (s * 0);
++m;
}
printf("\nwe are happy to annonce that:\n\nyour arival time will be at : %d %d %d\n\n\nhave a nice day!\n\n\n\n", h, m, s);
}
else printf("\nwrong value my friend!\n\n");
return 0;
}
if (m = 60) sets m to 60 and is true. You want to write if (m == 60).
The same for if (s = 60)

Finding a spotlight vector in openGL

I'm trying to find the proper vector for a direction of a spot light I have (I am trying to make it flashlight-like). I want it to face the same direction as the camera is always facing, like you're holding a flashlight out in front of you.
I can't seem to find the right directional vector, however.
At the moment, I have the light sort of following the front/back movement of the camera, but not the turn angle. In addition, the actual spot is pointed upwards, instead of directly ahead, like I want.
I know all the normals of the individual objects are working; I tested just general lighting already.
I'll just post code that's relevant to the question. If you really need my whole code, please say so.
Light code:
float sco=20; // Spot cutoff angle
float Exp=0; // Spot exponent
float Ambient[] = {0.01*ambient ,0.01*ambient ,0.01*ambient ,1.0};
float Diffuse[] = {0.01*diffuse ,0.01*diffuse ,0.01*diffuse ,1.0};
float Specular[] = {0.01*specular,0.01*specular,0.01*specular,1.0};
// Light direction
float Position[] = {Ox+3, 2, Oz,1};
float Direction[] = {Ox+lx, here, Oz+lz, 0};
glLightfv(GL_LIGHT0,GL_AMBIENT ,Ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE ,Diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,Specular);
glLightfv(GL_LIGHT0,GL_POSITION,Position);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,Direction);
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,sco);
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,Exp);
Camera code:
// Camera Values
double Ox=0, Oz=0;
float Oy=1.0;
float angle = 0.0;
float lx=0.0,lz=-1.0;
float deltaAngle = 0.0;
float deltaMove = 0;
double here;
void computePos(float deltaMove) {
Ox += deltaMove * lx * 0.1f;
Oz += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle) {
angle += deltaAngle;
lx = sin(angle);
lz = -cos(angle);
}
void display() {
here = 2.0f*Oy;
if (deltaMove)
computePos(deltaMove);
if (deltaAngle)
computeDir(deltaAngle);
gluLookAt(Ox,2,Oz, Ox+lx, here, Oz+lz, 0,1,0);
}
void key(unsigned char ch,int x,int y) {
// Exit on ESC
if (ch == 27)
exit(0);
// WASD controls
else if (ch == 'a' || ch == 'A')
deltaAngle = -0.01;
else if (ch == 'd' || ch == 'D')
deltaAngle = 0.01;
else if (ch == 'w' || ch == 'W') {
collidefront=collision(1);
collidextra=collision(3);
if (collideback == 2 && collidextra == 3) { deltaMove = 0; collideback = 0; }
else if (collideback == 2) { deltaMove = 0.1; collidefront = 0;}
else if (collidefront == 1) deltaMove = 0;
else
deltaMove = 0.1;
}
else if (ch == 's' || ch == 'S') {
collideback=collision(2);
if (collidefront == 1) { deltaMove = -0.3; collidefront = 0; }
else if (collideback == 2) deltaMove = 0;
else
deltaMove = -0.1;
}
else if ((ch == 'e' || ch == 'E') && here < 4)
Oy += 0.01;
else if ((ch == 'c' || ch == 'C') && here > .5)
Oy -= 0.01;
Project(fov,asp,dim);
glutPostRedisplay();
}
Thank you for your help.
Since you are using gluLookAt, you can easily compute the vector subtracting the center and the eye:
(...)
gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
(...)
spotlightVecX = centerX - eyeX;
spotlightVecY = centerY - eyeY;
spotlightVecZ = centerZ - eyeZ;
You may normalize it after you calculate the vector.
Hope it helps.

Resources