void AnimationEffectBurst::FlingRadial(float pRadialDegrees, float pSpeed) { FVec3 aPushSpeed = FVec3(Sin(pRadialDegrees), 0.0f, Cos(pRadialDegrees)); FVec3 aRotationAxis = FVec3(0.0f, 0.0f, 1.0f); aPushSpeed = Rotate3D(aPushSpeed, aRotationAxis, (180.0f - mOrbit)); aPushSpeed *= pSpeed; mVel += aPushSpeed; }
AnimationEffectBurst::AnimationEffectBurst() { mApp = gApp; mKillTimer = 200; mData = 0; mSequence = 0; mTexture = 0; mScale = 1.0f; mScaleAdd = 0.0f; mScaleDecay = 1.0f; mRotationX = 0.0f; mRotationY = 0.0f; mRotationZ = 0.0f; mRotationSpeedX = 0.0f; mRotationSpeedY = 0.0f; mRotationSpeedZ = 0.0f; mFrame = 0.0f; mFrameSpeed = 0.66f; mPlayOnce = false; mColorSpeedA = 0.0f; mColorSpeedR = 0.0f; mColorSpeedG = 0.0f; mColorSpeedB = 0.0f; mColorA = 1.0f; mColorR = 1.0f; mColorG = 1.0f; mColorB = 1.0f; mVel = FVec3(0.0f, 0.0f, 0.0f); mAccel = FVec3(1.0f, 1.0f, 1.0f); mColorAdditive = false; //mShiftU = 0.0f; //mShiftV = 0.0f; // // //mShiftSpeedU = 0.0f; //mShiftSpeedV = 0.0f; mVelAddZ = 0.0f; }
void Branch::Kaboom() { mHitRot = FVec3(0.0f, 0.0f, 0.0f); mHitPos = FVec3(0.0f, 0.0f, 0.0f); mHitRotSpeed = FVec3(gRand.GetFloat(-2.5f, -4.65f), gRand.GetFloat(-4.0f, 4.0f) , gRand.GetFloat(-2.0f, 2.0f)); float aPunch = gRand.GetFloat() * 0.15f + 0.075f; mHitSpeed = FVec3(mFacing.mX * aPunch + gRand.GetFloat(-0.025f, 0.025f), mFacing.mY * aPunch + gRand.GetFloat(-0.025f, 0.025f), gRand.GetFloat(0.0f, 0.25f)); mHit = true; }
FVec2 ZViewpoint::zviewpointProjOnPlane( int scnX, int scnY, FVec3 p0, FVec3 planeNrm ) { DMat4 modl = zviewpointReferenceModel; DMat4 _s = scale3D( DVec3(zviewpointScale, zviewpointScale, zviewpointScale)); modl.cat( _s ); DMat4 _t = trans3D( DVec3(zviewpointPermitTransX ? zviewpointTrans[0] : 0.f, zviewpointPermitTransY ? zviewpointTrans[1] : 0.f, zviewpointPermitTransZ ? zviewpointTrans[2] : 0.f)); modl.cat( _t ); FMat4 _v = zviewpointRotQuat.mat(); DMat4 rot = DMat4( _v ); rot.transpose(); modl.cat( rot ); if( zviewpointReferenceViewport[2]==0 || zviewpointReferenceViewport[3]==0 ) { // PROTECT against exception return FVec2( (float)0.f, (float)0.f ); } int viewport[4]; glGetIntegerv( GL_VIEWPORT, viewport ); DMat4 projMat; double world[2][3] = {0,}; gluUnProject( scnX, scnY, 0.f, modl, projMat, viewport, &world[0][0], &world[0][1], &world[0][2] ); gluUnProject( scnX, scnY, 1.f, modl, projMat, viewport, &world[1][0], &world[1][1], &world[1][2] ); FVec3 wp0 = zviewpointLinePlaneIntersect( FVec3::Origin, FVec3::ZAxis, FVec3((float)world[0][0],(float)world[0][1],(float)world[0][2]), FVec3((float)world[1][0],(float)world[1][1],(float)world[1][2]) ); return FVec2( (float)wp0.x, (float)wp0.y ); }
void PoisonFlower::Kaboom() { float aAngleDiff = DistanceBetweenAngles(gGame->mGecko.mOrbit, mOrbit); //FVec3 aFlingVector = GetFlingVector(aAngleDiff * 1.5f, 1.0f); //mHitSpeed = FVec3(aFlingVector.mX * 0.23f + mFacing.mX * 0.075f, aFlingVector.mY * 0.23f + mFacing.mY * 0.075f, gGame->mGecko.mSpeedClimb + 0.3f); mHitSpeed = FVec3(mFacing.mX * 0.205f, mFacing.mY * 0.205f, gGame->mGecko.mSpeedClimb + 0.3f); mHitRot = FVec3(0.0f, 0.0f, 0.0f); //mHitRotSpeed = FVec3(gRand.GetFloat(-2.0f, 2.0f), gRand.GetFloat(-4.123f, -6.5f), gRand.GetFloat(4.0f, 8.0f)); mHitRotSpeed = FVec3(5.0f, 1.666f, -1.0f); mHit = true; }
void ZViewpoint::zviewpointReset() { memset( &zviewpointTrans, 0, sizeof(zviewpointTrans) ); zviewpointRotQuat.fromAxisAngle( FVec3::XAxis, 0.f ); zviewpointScale = 1.f; zviewpointScaleAxes = FVec3( 1, 1, 1 ); zviewpointTransAxes = FVec3::Origin; zviewpointTarget = FVec3::Origin; // This was commented out but it being commented out caused a bug in that when one // plugin clears the rotation and the you switch to another then it can't rotate // It makes sense that startup should clear all this. zviewpointPermitRotX = 1; zviewpointPermitRotY = 1; zviewpointPermitRotZ = 1; zviewpointPermitTransX = 1; zviewpointPermitTransY = 1; zviewpointPermitTransZ = 1; zviewpointPermitScale = 1; }
void ZViewpoint::zviewpointHandleMsgTrackball( ZMsg *msg ) { static float viewpointMouseLast[2]; static int dragging = 0; float newzviewpointScale = 0.f; int scaleChange = 0; if( (zmsgIs(type,ZUIMouseClickOn) || zmsgIs(type,MouseClick)) && zmsgIs(dir,D) && (zmsgIs(which,R) || zmsgIs(which,M)) && zmsgI(shift) && zmsgI(ctrl) && zmsgI(alt) ) { // RESET memset( &zviewpointTrans, 0, sizeof(zviewpointTrans) ); zviewpointRotQuat.fromAxisAngle( FVec3::XAxis, 0.f ); zviewpointScale = 1.f; } char button = msg->getS( "which", "X" ) [0]; // if( (zmsgIs(type,ZUIMouseClickOn) || zmsgIs(type,MouseClick)) && zmsgIs(dir,D) && ( ( zmsgIs(which,M) && (zviewpointPermitRotX||zviewpointPermitRotY||zviewpointPermitRotZ) ) || zmsgIs(which,R) ) ) { if( (zmsgIs(type,ZUIMouseClickOn) || zmsgIs(type,MouseClick)) && zmsgIs(dir,D) && ( ( button==zviewpointRotateButton && (zviewpointPermitRotX||zviewpointPermitRotY||zviewpointPermitRotZ) ) || button==zviewpointTranslateButton ) ) { // I added the checks on permitrot but I think that this is probably temporay. I probably need to put in // some kind of better mapping system so that calling code can assign the mappings that they want // I had commented out the M button for some reason probably because // it conflicted with something. But I need it in Jarle. So this probably // needs to turn into a option but I will leave it on until // I see what it is that needs it turned off. Of course the // higher level thing could trap it and "zmsgUsed" to make ti disappear viewpointMouseLast[0] = zmsgF(x); viewpointMouseLast[1] = zmsgF(y); dragging = zMouseMsgRequestExclusiveDrag( "type=Viewpoint_MouseDrag" ); if( dragging ) { zviewpointRotating = button == zviewpointRotateButton; zviewpointTranslating = button == zviewpointTranslateButton; } zMsgUsed(); } else if( zmsgIs( type, KeyDown ) ) { if( zmsgIs( which, down ) ) { zviewpointRotateTrackball( 0.f, -zviewpointRotateStep ); zMsgUsed(); } if( zmsgIs( which, up ) ) { zviewpointRotateTrackball( 0.f, +zviewpointRotateStep ); zMsgUsed(); } if( zmsgIs( which, left ) ) { zviewpointRotateTrackball( +zviewpointRotateStep, 0.f ); zMsgUsed(); } if( zmsgIs( which, right ) ) { zviewpointRotateTrackball( -zviewpointRotateStep, 0.f ); zMsgUsed(); } } else if( (zmsgIs(type,Key) && zmsgIs(which,wheelforward)) || (zmsgIs(type,Key) && !strcmp(msg->getS("which"),",") ) ) { newzviewpointScale = zviewpointScale * 0.8f; scaleChange = 1; zMsgUsed(); } else if( (zmsgIs(type,Key) && zmsgIs(which,wheelbackward)) || (zmsgIs(type,Key) && !strcmp(msg->getS("which"),".") ) ) { newzviewpointScale = zviewpointScale * 1.2f; scaleChange = 1; zMsgUsed(); } if( scaleChange && zviewpointPermitScale ) { float x = (float)zMouseMsgX; float y = (float)zMouseMsgY; // I want the world coord at which the mouse is pointing before the zoom // to be the same as the world coord at which the mouse is pointing after the zoom // @TODO: convert his mess into a single function DMat4 preScale = zviewpointReferenceModel; DMat4 preScaleMat( scale3D( DVec3(zviewpointScale, zviewpointScale, zviewpointScale) ) ); preScale.cat( preScaleMat ); DVec3 pre0, pre1; gluUnProject( x, y, 0.f, preScale, zviewpointReferenceProj, zviewpointReferenceViewport, &pre0.x, &pre0.y, &pre0.z ); gluUnProject( x, y, 1.f, preScale, zviewpointReferenceProj, zviewpointReferenceViewport, &pre1.x, &pre1.y, &pre1.z ); FVec3 wp0 = zviewpointLinePlaneIntersect( FVec3::Origin, FVec3::ZAxis, FVec3((float)pre0.x,(float)pre0.y,(float)pre0.z), FVec3((float)pre1.x,(float)pre1.y,(float)pre1.z) ); DMat4 postScale = zviewpointReferenceModel; DMat4 postScaleMat = ( scale3D( DVec3(newzviewpointScale, newzviewpointScale, newzviewpointScale) ) ); postScale.cat( postScaleMat ); DVec3 post0, post1; gluUnProject( x, y, 0.f, postScale, zviewpointReferenceProj, zviewpointReferenceViewport, &post0.x, &post0.y, &post0.z ); gluUnProject( x, y, 1.f, postScale, zviewpointReferenceProj, zviewpointReferenceViewport, &post1.x, &post1.y, &post1.z ); FVec3 wp1 = zviewpointLinePlaneIntersect( FVec3::Origin, FVec3::ZAxis, FVec3((float)post0.x,(float)post0.y,(float)post0.z), FVec3((float)post1.x,(float)post1.y,(float)post1.z) ); wp1.sub( wp0 ); zviewpointTrans.add( wp1 ); zviewpointScale = newzviewpointScale; } if( zmsgIs(type,Viewpoint_MouseDrag) ) { if( zmsgI(releaseDrag) ) { zMouseMsgCancelExclusiveDrag(); zviewpointRotating = zviewpointTranslating = 0; } else { if( zviewpointRotating ) { float dx = +0.01f * ( viewpointMouseLast[0] - zmsgF(x) ); float dy = -0.01f * ( viewpointMouseLast[1] - zmsgF(y) ); float side = zmsgI( shift ) ? ( (zmsgF(localX) < zmsgF(w)/2) ? -1.f : 1.f ) : 0.f; // note: the side doesn't really work if the object is being rendered in a ZUI because the // w here refers to the screen, and not the ZUI. zviewpointRotateTrackball( dx, dy, side ); viewpointMouseLast[0] = zmsgF(x); viewpointMouseLast[1] = zmsgF(y); zMsgUsed(); } // else if( zmsgI(r) ) { else if( zviewpointTranslating ) { // COMPUTE how big is one pixel at the world z-plane of interest // For now, this plane normal to the camera and passes-though the origin // Do this by unprojecting rays at the mouse current and last and then // solving for the world position at the intersection of that plane // CAT in tranforms which take place before the translate DMat4 m = zviewpointReferenceModel; DMat4 _m( scale3D( DVec3(zviewpointScale, zviewpointScale, zviewpointScale) ) ); m.cat( _m ); DMat4 _m1( trans3D( DVec3(zviewpointTrans )) ); m.cat( _m1 ); DVec3 p0, p1, p2, p3; gluUnProject( zmsgF(x), zmsgF(y), 0.f, m, zviewpointReferenceProj, zviewpointReferenceViewport, &p0.x, &p0.y, &p0.z ); gluUnProject( zmsgF(x), zmsgF(y), 1.f, m, zviewpointReferenceProj, zviewpointReferenceViewport, &p1.x, &p1.y, &p1.z ); gluUnProject( viewpointMouseLast[0], viewpointMouseLast[1], 0.f, m, zviewpointReferenceProj, zviewpointReferenceViewport, &p2.x, &p2.y, &p2.z ); gluUnProject( viewpointMouseLast[0], viewpointMouseLast[1], 1.f, m, zviewpointReferenceProj, zviewpointReferenceViewport, &p3.x, &p3.y, &p3.z ); FVec3 wp0 = zviewpointLinePlaneIntersect( FVec3::Origin, FVec3::ZAxis, FVec3((float)p0.x,(float)p0.y,(float)p0.z), FVec3((float)p1.x,(float)p1.y,(float)p1.z) ); FVec3 wp1 = zviewpointLinePlaneIntersect( FVec3::Origin, FVec3::ZAxis, FVec3((float)p2.x,(float)p2.y,(float)p2.z), FVec3((float)p3.x,(float)p3.y,(float)p3.z) ); wp0.sub( wp1 ); FVec3 delta( wp0.x, wp0.y, 0.f ); if( zmsgI(shift) ) { delta.x = 0.f; delta.y = 0.f; delta.z = wp0.y * 4.f; } zviewpointTrans.add( delta ); viewpointMouseLast[0] = zmsgF(x); viewpointMouseLast[1] = zmsgF(y); zMsgUsed(); } } } }
void render() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); zviewpointSetupView(); const int MAX_TRIS = 1000000; static Triangle tris[MAX_TRIS]; int triCount = 0; const int steps = 60; const float stepsf = (float)steps; Rod r0( FVec3(-0.3f,0.f,0.f), FVec3(+0.f,0.f,0.f), Cloud_r ); Rod r1( FVec3(0.f,0.f,0.f), FVec3(0.2f,0.5f,0.f), Cloud_r ); Sphere s0( FVec3(-.5f, -.5f, 0.f), 0.25f ); Surface *surfaces[] = { (Surface *)&r0, (Surface *)&r1, (Surface *)&s0 }; int surfacesCount = sizeof(surfaces) / sizeof(surfaces[0]); float f[steps][steps][steps]; for( int xi=0; xi<steps; xi++ ) { for( int yi=0; yi<steps; yi++ ) { for( int zi=0; zi<steps; zi++ ) { FVec3 p( 2.f*(float)xi/stepsf-1.f, 2.f*(float)yi/stepsf-1.f, 2.f*(float)zi/stepsf-1.f ); f[xi][yi][zi] = 0.f; for( int i=0; i<surfacesCount; i++ ) { f[xi][yi][zi] += surfaces[i]->surface( p ); } } } } for( int xi=0; xi<steps-1; xi++ ) { for( int yi=0; yi<steps-1; yi++ ) { for( int zi=0; zi<steps-1; zi++ ) { GridCell g; float x0 = 2.f*(float)(xi+0)/stepsf-1.f; float x1 = 2.f*(float)(xi+1)/stepsf-1.f; float y0 = 2.f*(float)(yi+0)/stepsf-1.f; float y1 = 2.f*(float)(yi+1)/stepsf-1.f; float z0 = 2.f*(float)(zi+0)/stepsf-1.f; float z1 = 2.f*(float)(zi+1)/stepsf-1.f; g.p[0] = FVec3( x0, y0, z0 ); g.p[1] = FVec3( x1, y0, z0 ); g.p[2] = FVec3( x1, y1, z0 ); g.p[3] = FVec3( x0, y1, z0 ); g.p[4] = FVec3( x0, y0, z1 ); g.p[5] = FVec3( x1, y0, z1 ); g.p[6] = FVec3( x1, y1, z1 ); g.p[7] = FVec3( x0, y1, z1 ); g.val[0] = f[xi+0][yi+0][zi+0]; g.val[1] = f[xi+1][yi+0][zi+0]; g.val[2] = f[xi+1][yi+1][zi+0]; g.val[3] = f[xi+0][yi+1][zi+0]; g.val[4] = f[xi+0][yi+0][zi+1]; g.val[5] = f[xi+1][yi+0][zi+1]; g.val[6] = f[xi+1][yi+1][zi+1]; g.val[7] = f[xi+0][yi+1][zi+1]; triCount += polygonise( g, Cloud_r, &tris[triCount] ); assert( triCount < MAX_TRIS ); } } } DiscWarp dw( FVec3(-0.2f,0.f,0.f), FVec3(1.f,0.f,0.f) ); for( int i=0; i<triCount; i++ ) { tris[i].p[0] = dw.warp( tris[i].p[0] ); tris[i].p[1] = dw.warp( tris[i].p[1] ); tris[i].p[2] = dw.warp( tris[i].p[2] ); } dw.draw(); static unsigned int triList[MAX_TRIS*3]; static FVec3 normals[MAX_TRIS*3]; ZGLLight light0; light0.resetToDefaults(); light0.active = 1; light0.ambient[0] = 0.05f; light0.ambient[1] = 0.05f; light0.ambient[2] = 0.05f; light0.diffuse[0] = 0.8f; light0.diffuse[1] = 0.2f; light0.diffuse[2] = 0.2f; light0.dir[0] = 10.f; light0.dir[1] = 0.f; light0.dir[2] = 0.f; light0.makeDirectional(); light0.setLightNumber( 0 ); ZGLLight light1; light1.resetToDefaults(); light1.active = 1; light1.ambient[0] = 0.05f; light1.ambient[1] = 0.05f; light1.ambient[2] = 0.05f; light1.diffuse[0] = 0.2f; light1.diffuse[1] = 0.2f; light1.diffuse[2] = 0.8f; light1.dir[0] = -10.f; light1.dir[1] = -10.f; light1.dir[2] = 0.f; light1.makeDirectional(); light1.setLightNumber( 1 ); glEnable( GL_COLOR_MATERIAL ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_LIGHT1 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_NORMALIZE ); light0.setGL(); light1.setGL(); for( int i=0; i<triCount; i++ ) { FVec3 d10( tris[i].p[1] ); d10.sub( tris[i].p[0] ); FVec3 d20( tris[i].p[2] ); d20.sub( tris[i].p[0] ); normals[i*3+0] = d20; normals[i*3+0].cross( d10 ); FVec3 d01( tris[i].p[0] ); d01.sub( tris[i].p[1] ); FVec3 d21( tris[i].p[2] ); d21.sub( tris[i].p[1] ); normals[i*3+1] = d01; normals[i*3+1].cross( d21 ); FVec3 d02( tris[i].p[0] ); d02.sub( tris[i].p[2] ); FVec3 d12( tris[i].p[1] ); d12.sub( tris[i].p[2] ); normals[i*3+2] = d12; normals[i*3+2].cross( d02 ); triList[i*3+0] = i*3+0; triList[i*3+1] = i*3+1; triList[i*3+2] = i*3+2; } glColor3ub( 255, 255, 255 ); glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 3, GL_FLOAT, 0, &tris[0] ); glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer( GL_FLOAT, 0, &normals[0] ); glDrawElements( GL_TRIANGLES, triCount*3, GL_UNSIGNED_INT, &triList[0] ); }