1 /* 2 3 Copyright (c) 2002, Calum Robinson 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 9 * Redistributions of source code must retain the above copyright notice, this 10 list of conditions and the following disclaimer. 11 12 * Redistributions in binary form must reproduce the above copyright notice, 13 this list of conditions and the following disclaimer in the documentation 14 and/or other materials provided with the distribution. 15 16 * Neither the name of the author nor the names of its contributors may be used 17 to endorse or promote products derived from this software without specific 18 prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 */ 32 #include "Spark.h" 33 #include "Shared.h" 34 35 #define BIGMYSTERY 1800.0 36 #define MAXANGLES 16384 37 38 #define fieldCoherence 0 39 #define fieldSpeed 12.0f 40 #define fieldRange 1000.0f 41 42 void InitSpark(Spark *s) 43 { 44 int i; 45 for (i=0;i<3;i++) 46 { 47 s->position[i] = RandFlt(-100.0, 100.0); 48 } 49 } 50 51 void DrawSpark(flurry_info_t *info, Spark *s) 52 { 53 const float black[4] = {0.0f,0.0f,0.0f,1.0f}; 54 float width,sx,sy; 55 float a; 56 float c = 0.0625f; 57 float screenx; 58 float screeny; 59 float w,z, scale; 60 int k; 61 width = 60000.0f * info->sys_glWidth / 1024.0f; 62 63 z = s->position[2]; 64 sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f; 65 sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f; 66 w = width*4.0f / z; 67 68 screenx = sx; 69 screeny = sy; 70 71 glPushMatrix(); 72 glTranslatef(screenx,screeny,0.0f); 73 scale = w/50.0f; 74 glScalef(scale,scale,0.0f); 75 for (k=0;k<12;k++) 76 { 77 a = ((float) (random() % 3600)) / 10.0f; 78 glRotatef(a,0.0f,0.0f,1.0f); 79 glBegin(GL_QUAD_STRIP); 80 glColor4fv(black); 81 glVertex2f(-3.0f,0.0f); 82 a = 2.0f + (float) (random() & 255) * c; 83 glVertex2f(-3.0f,a); 84 glColor4fv(s->color); 85 glVertex2f(0.0f,0.0f); 86 glColor4fv(black); 87 glVertex2f(0.0f,a); 88 glVertex2f(3.0f,0.0f); 89 glVertex2f(3.0f,a); 90 glEnd(); 91 } 92 glPopMatrix(); 93 } 94 95 void UpdateSparkColour(flurry_info_t *info, Spark *s) 96 { 97 const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES); 98 double thisPointInRadians; 99 double thisAngle = info->fTime*rotationsPerSecond; 100 float cf; 101 float cycleTime = 20.0f; 102 float colorRot; 103 float redPhaseShift; 104 float greenPhaseShift; 105 float bluePhaseShift; 106 float baseRed; 107 float baseGreen; 108 float baseBlue; 109 float colorTime; 110 111 if (info->currentColorMode == rainbowColorMode) 112 { 113 cycleTime = 1.5f; 114 } 115 else if (info->currentColorMode == tiedyeColorMode) 116 { 117 cycleTime = 4.5f; 118 } 119 else if (info->currentColorMode == cyclicColorMode) 120 { 121 cycleTime = 20.0f; 122 } 123 else if (info->currentColorMode == slowCyclicColorMode) 124 { 125 cycleTime = 120.0f; 126 } 127 colorRot = (float) (2.0*M_PI/cycleTime); 128 redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */ 129 greenPhaseShift = cycleTime / 3.0f; 130 bluePhaseShift = cycleTime * 2.0f / 3.0f ; 131 colorTime = info->fTime; 132 if (info->currentColorMode == whiteColorMode) 133 { 134 baseRed = 0.1875f; 135 baseGreen = 0.1875f; 136 baseBlue = 0.1875f; 137 } 138 else if (info->currentColorMode == multiColorMode) 139 { 140 baseRed = 0.0625f; 141 baseGreen = 0.0625f; 142 baseBlue = 0.0625f; 143 } 144 else if (info->currentColorMode == darkColorMode) 145 { 146 baseRed = 0.0f; 147 baseGreen = 0.0f; 148 baseBlue = 0.0f; 149 } 150 else 151 { 152 if (info->currentColorMode < slowCyclicColorMode) 153 { 154 colorTime = (info->currentColorMode / 6.0f) * cycleTime; 155 } 156 else 157 { 158 colorTime = info->fTime + info->randomSeed; 159 } 160 baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f); 161 baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f); 162 baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f); 163 } 164 165 cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) + 166 cos(3.0*((info->fTime)*rotationsPerSecond)) + 167 cos(13.0*((info->fTime)*rotationsPerSecond)))); 168 cf /= 6.0f; 169 cf += 2.0f; 170 thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY; 171 172 s->color[0] = baseRed + 0.0625f * 173 (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) + 174 (float) sin((7.0 * (thisPointInRadians + thisAngle)))); 175 s->color[1] = baseGreen + 0.0625f * 176 (0.5f + (float) sin(((thisPointInRadians) + thisAngle))); 177 s->color[2] = baseBlue + 0.0625f * 178 (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle)))); 179 } 180 181 void UpdateSpark(flurry_info_t *info, Spark *s) 182 { 183 const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES); 184 double thisPointInRadians; 185 double thisAngle = info->fTime*rotationsPerSecond; 186 float cf; 187 int i; 188 double tmpX1,tmpY1,tmpZ1; 189 double tmpX2,tmpY2,tmpZ2; 190 double tmpX3,tmpY3,tmpZ3; 191 double tmpX4,tmpY4,tmpZ4; 192 double rotation; 193 double cr; 194 double sr; 195 float cycleTime = 20.0f; 196 float colorRot; 197 float redPhaseShift; 198 float greenPhaseShift; 199 float bluePhaseShift; 200 float baseRed; 201 float baseGreen; 202 float baseBlue; 203 float colorTime; 204 205 float old[3]; 206 207 if (info->currentColorMode == rainbowColorMode) { 208 cycleTime = 1.5f; 209 } else if (info->currentColorMode == tiedyeColorMode) { 210 cycleTime = 4.5f; 211 } else if (info->currentColorMode == cyclicColorMode) { 212 cycleTime = 20.0f; 213 } else if (info->currentColorMode == slowCyclicColorMode) { 214 cycleTime = 120.0f; 215 } 216 colorRot = (float) (2.0*M_PI/cycleTime); 217 redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */ 218 greenPhaseShift = cycleTime / 3.0f; 219 bluePhaseShift = cycleTime * 2.0f / 3.0f ; 220 colorTime = info->fTime; 221 if (info->currentColorMode == whiteColorMode) { 222 baseRed = 0.1875f; 223 baseGreen = 0.1875f; 224 baseBlue = 0.1875f; 225 } else if (info->currentColorMode == multiColorMode) { 226 baseRed = 0.0625f; 227 baseGreen = 0.0625f; 228 baseBlue = 0.0625f; 229 } else if (info->currentColorMode == darkColorMode) { 230 baseRed = 0.0f; 231 baseGreen = 0.0f; 232 baseBlue = 0.0f; 233 } else { 234 if(info->currentColorMode < slowCyclicColorMode) { 235 colorTime = (info->currentColorMode / 6.0f) * cycleTime; 236 } else { 237 colorTime = info->fTime + info->randomSeed; 238 } 239 baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f); 240 baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f); 241 baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f); 242 } 243 244 for (i=0;i<3;i++) { 245 old[i] = s->position[i]; 246 } 247 248 cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) + 249 cos(3.0*((info->fTime)*rotationsPerSecond)) + 250 cos(13.0*((info->fTime)*rotationsPerSecond)))); 251 cf /= 6.0f; 252 cf += 2.0f; 253 thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY; 254 255 s->color[0] = baseRed + 0.0625f * 256 (0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) + 257 (float) sin((7.0 * (thisPointInRadians + thisAngle)))); 258 s->color[1] = baseGreen + 0.0625f * 259 (0.5f + (float) sin(((thisPointInRadians) + thisAngle))); 260 s->color[2] = baseBlue + 0.0625f * 261 (0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle)))); 262 s->position[0] = fieldRange * cf * 263 (float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle))); 264 s->position[1] = fieldRange * cf * 265 (float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle))); 266 s->position[2] = fieldRange * 267 (float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle)))); 268 269 rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY; 270 cr = cos(rotation); 271 sr = sin(rotation); 272 tmpX1 = s->position[0] * cr - s->position[1] * sr; 273 tmpY1 = s->position[1] * cr + s->position[0] * sr; 274 tmpZ1 = s->position[2]; 275 276 tmpX2 = tmpX1 * cr - tmpZ1 * sr; 277 tmpY2 = tmpY1; 278 tmpZ2 = tmpZ1 * cr + tmpX1 * sr; 279 280 tmpX3 = tmpX2; 281 tmpY3 = tmpY2 * cr - tmpZ2 * sr; 282 tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance; 283 284 rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (double) BIGMYSTERY; 285 cr = cos(rotation); 286 sr = sin(rotation); 287 tmpX4 = tmpX3 * cr - tmpY3 * sr; 288 tmpY4 = tmpY3 * cr + tmpX3 * sr; 289 tmpZ4 = tmpZ3; 290 291 s->position[0] = (float) tmpX4 + RandBell(5.0f*fieldCoherence); 292 s->position[1] = (float) tmpY4 + RandBell(5.0f*fieldCoherence); 293 s->position[2] = (float) tmpZ4 + RandBell(5.0f*fieldCoherence); 294 295 for (i=0;i<3;i++) { 296 s->delta[i] = (s->position[i] - old[i])/info->fDeltaTime; 297 } 298 } 299