#include "stdafx.h" #include "PlanetaryBody.h" #include "glext.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// planetaryBody::planetaryBody() :pParent(NULL), planetName (""), orbitDistance(0.0f), orbitSpeed(0.0f), Radius(1.0f), rotationalSpeed(0.0), lastUpdate(0), Shininess(1.0), Slices(30), Stacks(30), currentRotation(0.0f), currentOrbit(0.0f), sunLight(GL_LIGHT1), isSun(false), axisTilt(0.0f) { Ambient[0]=0.2; Ambient[1]=0.2; Ambient[2]=0.2; Ambient[3] = 1.0; Diffuse[0]=0.8; Diffuse[1]=0.8; Diffuse[2]=0.8; Diffuse[3] = 1.0; Specular[0]=0.0; Specular[1]=0.0; Specular[2]=0.0; Specular[3] = 1.0; Emission[0]=0.0; Emission[1]=0.0; Emission[2]=0.0; Emission[3] = 1.0; axisTiltPlane[0]=1.0; axisTiltPlane[1]=0.0; axisTiltPlane[2]=0.0; } planetaryBody::~planetaryBody() { planetaryBodyList::iterator itr; for (itr = childList.begin(); itr != childList.end(); itr++) { planetaryBody* pChild = *itr; delete pChild; } } // Updates the world position of the planet, then repositions the children void planetaryBody::Update() { glPushMatrix(); glRotatef(axisTilt, axisTiltPlane[0], axisTiltPlane[1], axisTiltPlane[2]); glRotatef(currentOrbit, 0.0, 1.0, 0.0); glTranslatef(orbitDistance, 0.0, 0.0); glPushMatrix(); if (isSun) { float pLightDir[] = {0.0, 0.0, 1.0, 0.0}; float pLightDiffuse[] = {1.0, 1.0, 0.0, 1.0}; float pLightSpecular[] = {0.3, 0.0, 1.0, 1.0}; glEnable(sunLight); glLightfv(sunLight, GL_POSITION, pLightDir); glLightfv(sunLight, GL_DIFFUSE, pLightDiffuse); glLightfv(sunLight, GL_SPECULAR, pLightSpecular); } glRotatef(currentRotation, 0.0, 1.0, 0.0); DrawBody(); if (isSun) { glDisable(sunLight); } glPopMatrix(); planetaryBodyList::iterator itr; for (itr = childList.begin(); itr != childList.end(); itr++) { planetaryBody* pChild = *itr; pChild->Update(); } glPopMatrix(); // Update the rotations if (lastUpdate != 0) { float fSecs = static_cast(GetTime() - lastUpdate)/1000.0; currentOrbit += orbitSpeed * fSecs; currentRotation += rotationalSpeed * fSecs; if (currentOrbit > 360.0) currentOrbit -= 360.0; if (currentOrbit < -360.0) currentOrbit +=360.0; if (currentRotation > 360.0) currentRotation -= 360.0; if (currentRotation < -360.0) currentRotation +=360.0; } lastUpdate = GetTime(); } // Creates a satelite object planetaryBody* planetaryBody::CreateChild() { planetaryBody* pChild = new planetaryBody; pChild->pParent = this; childList.push_back(pChild); return pChild; } void planetaryBody::SetMaterialProperty(GLenum eProp, float *pValue) { switch(eProp) { case GL_AMBIENT_AND_DIFFUSE: Ambient[0] = Diffuse[0] = pValue[0]; Ambient[1] = Diffuse[1] = pValue[1]; Ambient[2] = Diffuse[2] = pValue[2]; Ambient[3] = Diffuse[3] = pValue[3]; break; case GL_AMBIENT: Ambient[0] = pValue[0]; Ambient[1] = pValue[1]; Ambient[2] = pValue[2]; Ambient[3] = pValue[3]; break; case GL_DIFFUSE: Diffuse[0] = pValue[0]; Diffuse[1] = pValue[1]; Diffuse[2] = pValue[2]; Diffuse[3] = pValue[3]; break; case GL_SPECULAR: Specular[0] = pValue[0]; Specular[1] = pValue[1]; Specular[2] = pValue[2]; Specular[3] = pValue[3]; break; case GL_EMISSION: Emission[0] = pValue[0]; Emission[1] = pValue[1]; Emission[2] = pValue[2]; Emission[3] = pValue[3]; break; case GL_SHININESS: Shininess = *pValue; break; } } void planetaryBody::GetMaterialProp(GLenum eProp, float *pValue) const { switch(eProp) { case GL_AMBIENT_AND_DIFFUSE: pValue[0] = (Ambient[0] + Diffuse[0]) / 2.0; pValue[1] = (Ambient[1] + Diffuse[1]) / 2.0; pValue[2] = (Ambient[2] + Diffuse[2]) / 2.0; pValue[3] = (Ambient[3] + Diffuse[3]) / 2.0; break; case GL_AMBIENT: pValue[0] = Ambient[0]; pValue[1] = Ambient[1]; pValue[2] = Ambient[2]; pValue[3] = Ambient[3]; break; case GL_DIFFUSE: pValue[0] = Diffuse[0]; pValue[1] = Diffuse[1]; pValue[2] = Diffuse[2]; pValue[3] = Diffuse[3]; break; case GL_SPECULAR: pValue[0] = Specular[0]; pValue[1] = Specular[1]; pValue[2] = Specular[2]; pValue[3] = Specular[3]; break; case GL_EMISSION: pValue[0] = Emission[0]; pValue[1] = Emission[1]; pValue[2] = Emission[2]; pValue[3] = Emission[3]; break; case GL_SHININESS: pValue[0] = Shininess; break; } } void planetaryBody::DrawBody() { glMaterialfv(GL_FRONT, GL_AMBIENT, Ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, Diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, Specular); glMaterialfv(GL_FRONT, GL_EMISSION, Emission); glMaterialf(GL_FRONT, GL_SHININESS, Shininess); GLUquadricObj* pSphere = gluNewQuadric(); gluQuadricNormals(pSphere, GLU_SMOOTH); gluSphere(pSphere, Radius, Slices, Stacks); gluDeleteQuadric(pSphere); } int planetaryBody::GetTime() { timeb t; ftime(&t); return 1000 * t.time + t.millitm; }