// transform model to view space static void PrepareView( CRenderModel &rm) { // prepare projections const FLOATmatrix3D &mViewer = _aprProjection->pr_ViewerRotationMatrix; const FLOAT3D &vViewer = _aprProjection->pr_vViewerPosition; FLOATmatrix3D &m = rm.rm_mObjectToView; // if half face forward if( rm.rm_pmdModelData->md_Flags&MF_HALF_FACE_FORWARD) { // get the y-axis vector of object rotation FLOAT3D vY(rm.rm_mObjectRotation(1,2), rm.rm_mObjectRotation(2,2), rm.rm_mObjectRotation(3,2)); // find z axis of viewer FLOAT3D vViewerZ( mViewer(3,1), mViewer(3,2), mViewer(3,3)); // calculate x and z axis vectors to make object head towards viewer FLOAT3D vX = (-vViewerZ)*vY; vX.Normalize(); FLOAT3D vZ = vY*vX; // compose the rotation matrix back from those angles m(1,1) = vX(1); m(1,2) = vY(1); m(1,3) = vZ(1); m(2,1) = vX(2); m(2,2) = vY(2); m(2,3) = vZ(2); m(3,1) = vX(3); m(3,2) = vY(3); m(3,3) = vZ(3); // add viewer rotation to that m = mViewer * m; } // if full face forward else if( rm.rm_pmdModelData->md_Flags&MF_FACE_FORWARD) { // use just object banking for rotation FLOAT fSinP = -rm.rm_mObjectRotation(2,3); FLOAT fCosP = Sqrt(1-fSinP*fSinP); FLOAT fSinB, fCosB; if( fCosP>0.001f) { const FLOAT f1oCosP = 1.0f/fCosP; fSinB = rm.rm_mObjectRotation(2,1)*f1oCosP; fCosB = rm.rm_mObjectRotation(2,2)*f1oCosP; } else { fSinB = 0.0f; fCosB = 1.0f; } m(1,1) = +fCosB; m(1,2) = -fSinB; m(1,3) = 0; m(2,1) = +fSinB; m(2,2) = +fCosB; m(2,3) = 0; m(3,1) = 0; m(3,2) = 0; m(3,3) = 1; } // if normal model else { // use viewer and object orientation m = mViewer * rm.rm_mObjectRotation; } // find translation vector rm.rm_vObjectToView = rm.rm_vObjectPosition - vViewer; rm.rm_vObjectToView *= mViewer; }
void XSQUARE_MATRIX::Invert_LUD(void) { // Invert the matrix using LU decomposition Perform_LU_Decomposition(); if (m_lpdValues && m_bLU_Initialized) { if (g_lpvX == NULL || g_uiX_Size < m_uiN) { if (g_lpvX) delete [] g_lpvX; g_lpvX = new XVECTOR[m_uiN]; g_uiX_Size = m_uiN; } XVECTOR vB(m_uiN); XVECTOR vY(m_uiN); for (unsigned int uiI = 0; uiI < m_uiN; uiI++) vB.Set(uiI,0.0); for (unsigned int uiI = 0; uiI < m_uiN; uiI++) { if (uiI != 0) vB.Set(uiI - 1,0.0); vB.Set(uiI,1.0); vY = Forward_Substituion(vB); g_lpvX[uiI] = Back_Substituion(m_lpdU_Values,vY); } // Inverse found (stored in the array of X vectors) // no refill matrix for (unsigned int uiI = 0; uiI < m_uiN; uiI++) Set(uiI, g_lpvX[uiI]); m_bLU_Initialized = false; // Get LU decomposition of inverted matrix Perform_LU_Decomposition(); } }
Mat CmSaliencyRC::GetBorderReg(CMat &idx1i, int regNum, double ratio, double thr) { // Variance of x and y vecD vX(regNum), vY(regNum); int w = idx1i.cols, h = idx1i.rows;{ vecD mX(regNum), mY(regNum), n(regNum); // Mean value of x and y, pixel number of region for (int y = 0; y < idx1i.rows; y++){ const int *idx = idx1i.ptr<int>(y); for (int x = 0; x < idx1i.cols; x++, idx++) mX[*idx] += x, mY[*idx] += y, n[*idx]++; } for (int i = 0; i < regNum; i++) mX[i] /= n[i], mY[i] /= n[i]; for (int y = 0; y < idx1i.rows; y++){ const int *idx = idx1i.ptr<int>(y); for (int x = 0; x < idx1i.cols; x++, idx++) vX[*idx] += abs(x - mX[*idx]), vY[*idx] += abs(y - mY[*idx]); } for (int i = 0; i < regNum; i++) vX[i] = vX[i]/n[i] + EPS, vY[i] = vY[i]/n[i] + EPS; } // Number of border pixels in x and y border region vecI xbNum(regNum), ybNum(regNum); int wGap = cvRound(w * ratio), hGap = cvRound(h * ratio); vector<Point> bPnts; { ForPoints2(pnt, 0, 0, w, hGap) // Top region ybNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, 0, h - hGap, w, h) // Bottom region ybNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, 0, 0, wGap, h) // Left region xbNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); ForPoints2(pnt, w - wGap, 0, w, h) xbNum[idx1i.at<int>(pnt)]++, bPnts.push_back(pnt); } Mat bReg1u(idx1i.size(), CV_8U);{ // likelihood map of border region double xR = 1.0/(4*hGap), yR = 1.0/(4*wGap); vector<byte> regL(regNum); // likelihood of each region belongs to border background for (int i = 0; i < regNum; i++) { double lk = xbNum[i] * xR / vY[i] + ybNum[i] * yR / vX[i]; regL[i] = lk/thr > 1 ? 255 : 0; //saturate_cast<byte>(255 * lk / thr); } for (int r = 0; r < h; r++) { const int *idx = idx1i.ptr<int>(r); byte* maskData = bReg1u.ptr<byte>(r); for (int c = 0; c < w; c++, idx++) maskData[c] = regL[*idx]; } } for (size_t i = 0; i < bPnts.size(); i++) bReg1u.at<byte>(bPnts[i]) = 255; return bReg1u; }
// mirror a placement of one entity static void MirrorAndStretchPlacement(CPlacement3D &pl) { ASSERT(_wmtMirror==WMT_X||_wmtMirror==WMT_Y||_wmtMirror==WMT_Z||_wmtMirror==WMT_NONE); // if there should be mirror if (_wmtMirror!=WMT_NONE) { // make rotation matrix for the placement FLOATmatrix3D m; MakeRotationMatrix(m, pl.pl_OrientationAngle); // get row vectors, with object x flipped FLOAT3D vX(-m(1,1),m(1,2),m(1,3)); FLOAT3D vY(-m(2,1),m(2,2),m(2,3)); FLOAT3D vZ(-m(3,1),m(3,2),m(3,3)); // flip needed axis switch(_wmtMirror) { case WMT_X: pl.pl_PositionVector(1) = -pl.pl_PositionVector(1); vX = -vX; break; case WMT_Y: pl.pl_PositionVector(2) = -pl.pl_PositionVector(2); vY = -vY; break; case WMT_Z: pl.pl_PositionVector(3) = -pl.pl_PositionVector(3); vZ = -vZ; break; default: ASSERT(FALSE); } // compose matrix back from the vectors m(1,1) = vX(1); m(2,1) = vY(1); m(3,1) = vZ(1); m(1,2) = vX(2); m(2,2) = vY(2); m(3,2) = vZ(2); m(1,3) = vX(3); m(2,3) = vY(3); m(3,3) = vZ(3); // decompose matrix into angles DecomposeRotationMatrix(pl.pl_OrientationAngle, m); } pl.pl_PositionVector*=_fStretch; }
XVECTOR XSQUARE_MATRIX::Solve_LU(const XVECTOR &i_vB) { XVECTOR vX; Perform_LU_Decomposition(); if (m_lpdValues && i_vB.m_lpdValues && i_vB.m_uiN == m_uiN && m_bLU_Initialized) { XVECTOR vY(m_uiN); vY = Forward_Substituion(i_vB); vX = Back_Substituion(m_lpdU_Values,vY); } return vX; }
static void findMaxMinPercentile(FIBITMAP *Y, float minPrct, float *minLum, float maxPrct, float *maxLum) { int x, y; int width = FreeImage_GetWidth(Y); int height = FreeImage_GetHeight(Y); int pitch = FreeImage_GetPitch(Y); std::vector<float> vY(width * height); BYTE *bits = (BYTE*)FreeImage_GetBits(Y); for(y = 0; y < height; y++) { float *pixel = (float*)bits; for(x = 0; x < width; x++) { if(pixel[x] != 0) { vY.push_back(pixel[x]); } } bits += pitch; } std::sort(vY.begin(), vY.end()); *minLum = vY.at( int(minPrct * vY.size()) ); *maxLum = vY.at( int(maxPrct * vY.size()) ); }
void CommandDisplayClipPropertiesDialog::ExecuteE() { EMMediaType eType(EM_TYPE_UNKNOWN); EMGClip* opClip; EMGTrack* opTrack; EMGUIUtilities* opGUIUtilities = EMGUIUtilities::Instance(); EMCommandRepository* opRepository = EMCommandRepository::Instance(); int32 vClipID(0); int32 vEntryID(-1); int64 vValue(0); int32 vX(0); int32 vY(0); string oFileName; char vTemp[100]; list<EMGClip*>* opClips = EMGClipRepository::Instance() -> GetSelectedClips(); list<EMGClip*>::iterator oClipIterator = opClips -> begin(); if(opClips -> size() == 0) return; while(oClipIterator != opClips -> end()) { opClip = *oClipIterator; eType = opClip -> GetType(); opTrack = opClip -> GetTrack(); switch(eType) { case EM_TYPE_ANY_AUDIO: vClipID = opClip ->GetMediaClipID(); vEntryID = *static_cast<int32*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_ENTRY_ID, &vClipID, NULL, NULL)); m_oAudioDialog.SetNameValue(opClip -> GetLabel()); m_oAudioDialog.SetTypeValue("Audio"); m_oAudioDialog.SetBeginValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition(), EM_SMPTE)); m_oAudioDialog.SetEndValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition() + opClip -> GetLength(), EM_SMPTE)); m_oAudioDialog.SetDurationValue(opGUIUtilities -> GetTimeString(opClip -> GetLength(), EM_SMPTE)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_AUDIO_ENTRY_NUM_CHANNELS, &vEntryID)); m_oAudioDialog.SetChannelsValue(_i64toa(vValue, vTemp, 10)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_AUDIO_ENTRY_NUM_SAMPLES, &vEntryID)); m_oAudioDialog.SetSamplesValue(_i64toa(vValue, vTemp, 10)); oFileName = static_cast<const char*>(EMCommandRepository::Instance() -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_ENTRY_FILENAME, &vEntryID)); //Full path to copied file oFileName.erase(0, oFileName.find_last_of('\\') + 1); //oFileName.erase(oFileName.find_last_of('.')); m_oAudioDialog.SetFileValue(oFileName); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_ENTRY_DURATION, &vEntryID)); m_oAudioDialog.SetFileLengthValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_MARK_IN, &vClipID)); m_oAudioDialog.SetMarkInValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_MARK_OUT, &vClipID)); m_oAudioDialog.SetMarkOutValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); m_oAudioDialog.Init(vX, vY, AUDIO); CalculatePosition(vX, vY, opClip, opTrack -> GetTrackInfo(), &m_oAudioDialog); m_oAudioDialog.MoveDialog(vX, vY); m_oAudioDialog.DisplayDialog(); break; case EM_TYPE_MIDI: { char vTemp[100]; uint32 vEvents(0); m_oMidiDialog.SetNameValue(opClip -> GetLabel()); m_oMidiDialog.SetTypeValue("Midi"); m_oMidiDialog.SetBeginValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition(), EM_MEASURES)); m_oMidiDialog.SetEndValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition() + opClip -> GetLength(), EM_MEASURES)); m_oMidiDialog.SetDurationValue(opGUIUtilities -> GetTimeString(opClip -> GetLength(), EM_MEASURES)); int32 vMediaClipID(opClip ->GetMediaClipID()); vEvents = (static_cast<list<EMMediaMIDIEvent*>*>(EMCommandRepository::Instance() -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_MIDI_EVENTS_FOR_CLIP, &vMediaClipID, NULL, NULL))) -> size(); m_oMidiDialog.SetEventValue(string(itoa(vEvents, vTemp, 10))); m_oMidiDialog.Init(vX, vY, MIDI); CalculatePosition(vX, vY, opClip, opTrack -> GetTrackInfo(), &m_oMidiDialog); m_oMidiDialog.MoveDialog(vX, vY); m_oMidiDialog.DisplayDialog(); break; } case EM_TYPE_ANY_VIDEO: vClipID = opClip ->GetMediaClipID(); vEntryID = *static_cast<int32*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_ENTRY_ID, &vClipID, NULL, NULL)); m_oVideoDialog.SetNameValue(opClip -> GetLabel()); m_oVideoDialog.SetTypeValue("Video"); m_oVideoDialog.SetBeginValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition(), EM_SMPTE)); m_oVideoDialog.SetEndValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition() + opClip -> GetLength(), EM_SMPTE)); m_oVideoDialog.SetDurationValue(opGUIUtilities -> GetTimeString(opClip -> GetLength(), EM_SMPTE)); // vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_VIDEO_ENTRY_NUM_FRAMES, &vEntryID)); // m_oVideoDialog.SetSamplesValue(_i64toa(vValue, vTemp, 10)); oFileName = static_cast<const char*>(EMCommandRepository::Instance() -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_ENTRY_FILENAME, &vEntryID)); //Full path to copied file oFileName.erase(0, oFileName.find_last_of('\\') + 1); //oFileName.erase(oFileName.find_last_of('.')); m_oVideoDialog.SetFileValue(oFileName); m_oVideoDialog.SetDimentionValue(static_cast<const char*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_VIDEO_DIMENSION, &vEntryID))); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_ENTRY_DURATION, &vEntryID)); m_oVideoDialog.SetFileLengthValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_MARK_IN, &vClipID)); m_oVideoDialog.SetMarkInValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); vValue = *static_cast<int64*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_MARK_OUT, &vClipID)); m_oVideoDialog.SetMarkOutValue(opGUIUtilities -> GetTimeString(vValue, EM_SMPTE)); m_oVideoDialog.Init(vX, vY, VIDEO); CalculatePosition(vX, vY, opClip, opTrack -> GetTrackInfo(), &m_oVideoDialog); m_oVideoDialog.MoveDialog(vX, vY); m_oVideoDialog.DisplayDialog(); break; case EM_TYPE_TRANSITION: vClipID = opClip ->GetMediaClipID(); // vEntryID = *static_cast<int32*>(opRepository -> ExecuteCommand(MEDIA_INFO_COMMAND_GET_CLIP_ENTRY_ID, &vClipID, NULL, NULL)); m_oTransitionDialog.SetNameValue(opClip -> GetLabel()); m_oTransitionDialog.SetTypeValue("Transition"); m_oTransitionDialog.SetBeginValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition(), EM_SMPTE)); m_oTransitionDialog.SetEndValue(opGUIUtilities -> GetTimeString(opClip -> GetPosition() + opClip -> GetLength(), EM_SMPTE)); m_oTransitionDialog.SetDurationValue(opGUIUtilities -> GetTimeString(opClip -> GetLength(), EM_SMPTE)); m_oTransitionDialog.Init(vX, vY, TRANSITION); CalculatePosition(vX, vY, opClip, opTrack -> GetTrackInfo(), &m_oTransitionDialog); m_oTransitionDialog.MoveDialog(vX, vY); m_oTransitionDialog.DisplayDialog(); break; } vX = 0; vY = 0; oClipIterator++; } }
void fxGetParticleSystemProps( CFastList<CEffectPropertyDesc> *pList ) { CEffectPropertyDesc fxProp; LTVector vY(0, 1.0f, 0); LTVector vZero(0, 0, 0); // Add the generic "every effect has these" props AddBaseProps( pList ); // Add specific Particle System Props //------------------------------------------------------------ fxProp.SetupTextLine("System Rendering"); pList->AddTail(fxProp); fxProp.SetupPath( "Material", "", "Material Files (*." RESEXT_MATERIAL ")|*." RESEXT_MATERIAL "|All Files (*.*)|*.*||", eCurve_None, "The material to use when rendering the particles. This material should be rigid, and if the alpha of the particle is not 1, should also be translucent." ); pList->AddTail( fxProp ); fxProp.SetupIntMinMax( "NumImages", 1, 1, CParticleSystemProps::knMaxParticleImages, eCurve_None, "The number of images contained within the textures used by the particle. These must be laid out in a horizontal strip, with each image occupying the same width." ); pList->AddTail( fxProp ); fxProp.SetupEnumBool( "Solid", false, eCurve_None, "Determines if this particle system should be treated as opaque or translucent" ); pList->AddTail( fxProp ); fxProp.SetupEnumBool( "TranslucentLight", true, eCurve_None, "For translucent objects, this determines if lighting should be approximated or if it should be fullbright" ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("System Behavior"); pList->AddTail(fxProp); fxProp.SetupEnumBool( "PlayerView", false, eCurve_None, "Determines if the sprite should be rendered in the player view, which means that it should have its Z values adjusted to not be clipped into nearby walls"); pList->AddTail( fxProp ); fxProp.SetupEnum( "InSky", SKY_PROP_DEFAULT, SKY_PROP_ENUM, eCurve_None, SKY_PROP_DESCRIPTION); pList->AddTail( fxProp ); fxProp.SetupEnumBool( "MoveParticlesWithSystem", false, eCurve_None, "If this is enabled, the particles will move along with the emitter. This will cause the particle positions, velocity, and additional acceleration to all be specified in object space." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin( "GroupCreationInterval", 0.0f, 0.0f, eCurve_None, "This indicates the amount of time that will elapse before a new group is created for the particles to be placed within. This should be set to zero to disable creation of multiple groups"); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Emission"); pList->AddTail(fxProp); fxProp.SetupFloat( "EmissionInterval", 0.1f, eCurve_None, "This is the rate that batches of particles will be emitted from the particle system. This is measured in seconds, so .1 will emit every .1 seconds, or 10 times a second. This should be set to zero if only a single emission should occur." ); pList->AddTail( fxProp ); fxProp.SetupIntMin( "ParticlesPerEmission", 5, 0, eCurve_Linear, "Indicates the number of particles that will be emitted per batch." ); pList->AddTail( fxProp ); fxProp.SetupEnum( "EmissionType", "Sphere", "Sphere, Point, Cone, Cylinder, Box", eCurve_None, "The primitive to use for emitting the particles." ); pList->AddTail( fxProp ); fxProp.SetupVector( "EmissionDir", vY, eCurve_None, "The direction to aim the emission primitive. This is used for cone and cylinder to aim the direction of them." ); pList->AddTail( fxProp ); fxProp.SetupVector( "EmissionOffset", vZero, eCurve_Linear, "An additional offset from the position of the object that will be applied to where particles are emitted. For example, if a particle system is attached to a model, but should be offset in the Y direction this can be used to offset the point of emission." ); pList->AddTail( fxProp ); fxProp.SetupVectorMin( "EmissionDims", vZero, 0.0f, eCurve_Linear, "This indicates the dimensions of the area to emit in. For box all three are used to determine the half dimensions of the box, for cylinder and cone though, the Y component is used to indicate the height." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin( "EmissionMinRadius", 0.0f, 0.0f, eCurve_Linear, "The minimum radius to use for the sphere, cone, and cylinder emission types." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin( "EmissionMaxRadius", 10.0f, 0.0f, eCurve_Linear, "The maximum radius to use for the sphere, cone, and cylinder emission types." ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Properties"); pList->AddTail(fxProp); fxProp.SetupColor( "ParticleColor", 0xFFFFFFFF, eCurve_Linear, "The color of the particles over the course of each particle's lifetime." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin("ParticleScale", 10.0f, 0.0f, eCurve_Linear, "This controls the size of the particles over the course of each particle's lifetime"); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Lifetime"); pList->AddTail(fxProp); fxProp.SetupFloatMin( "MinParticleLifeSpan", 2.0f, 0.0f, eCurve_Linear, "The minimum length of time that a particle will live for, measured in seconds. Ignored if the particles have infinite life." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin( "MaxParticleLifeSpan", 3.0f, 0.0f, eCurve_Linear, "The maximum length of time that a particle will live for, measured in seconds. Ignored if the particles have infinite life." ); pList->AddTail( fxProp ); fxProp.SetupEnumBool( "InfiniteLife", false, eCurve_None, "Specifies whether or not the particles created should last until the end of the effect, or disappear when their lifetime expires" ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Gravity"); pList->AddTail(fxProp); fxProp.SetupFloat( "GravityScale", 1.0f, eCurve_Linear, "Indicates how much gravity will influence the particles. Zero indicates that gravity will not effect the system, and one indicates that gravity will have normal effect. Values outside of this range can be used for other effects such as negative gravity, or exceptionally fast gravity" ); pList->AddTail( fxProp ); fxProp.SetupVector( "AdditionalAcceleration", vZero, eCurve_Linear, "Indicates an additional acceleration to apply to the particles. This acts very much like additional gravity, but can be specified in any direction and can change over time." ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Velocity"); pList->AddTail(fxProp); fxProp.SetupEnum( "VelocityType", "Random", "Random, FromCenter", eCurve_None, "The method to use when determining the initial linear velocity to use for the particles. Random will pick a random value within the range specified below, while FromCenter will use the direction from the center as the velocity direction, and the X component of the below values to determine the speed" ); pList->AddTail( fxProp ); fxProp.SetupVector( "MinParticleVelocity", vY, eCurve_Linear, "The minimum range for the velocities to use when randomly determining the particle velocity. This is in cm per second, and only the X is used for FromCenter" ); pList->AddTail( fxProp ); fxProp.SetupVector( "MaxParticleVelocity", vY, eCurve_Linear, "The maximum range for the velocities to use when randomly determining the particle velocity. This is in cm per second, and only the X is used for FromCenter" ); pList->AddTail( fxProp ); fxProp.SetupFloatMinMax( "Drag", 0.0f, 0.0f, 1.0f, eCurve_Linear, "Indicates the amount of drag on the particles. This ranges from zero to one, where zero means no drag, and one means full drag, stopping the particles from moving." ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Rotation"); pList->AddTail(fxProp); fxProp.SetupEnumBool( "RotateParticles", false, eCurve_None, "Determines whether or not the particles will rotate. This cannot be used with streaks and does incur some additional cost." ); pList->AddTail( fxProp ); fxProp.SetupFloat( "MinAngularVelocity", 0.0f, eCurve_None, "If RotateParticles is enabled, this will indicate the minimum rotational velocity of the particles in radians per second." ); pList->AddTail( fxProp ); fxProp.SetupFloat( "MaxAngularVelocity", 360.0f, eCurve_None, "If RotateParticles is enabled, this will indicate the maximum rotational velocity of the particles in radians per second." ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Streaks"); pList->AddTail(fxProp); fxProp.SetupEnumBool( "Streak", false, eCurve_None, "Determines if the particles should be streaked based upon their current velocity. This cannot be used with rotating particles." ); pList->AddTail( fxProp ); fxProp.SetupFloat( "StreakScale", 1.0f, eCurve_None, "The scale of the streak to apply. The larger this number, the more the particles will streak. At 1.0, a particle going 1 cm/s will stream one unit, so setting this to 10 will make it streak ten times as large and so on."); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Bounce"); pList->AddTail(fxProp); fxProp.SetupEnumBool( "EnableBounceScale", true, eCurve_None, "Determines whether or not the global scaling of particle bouncing should be applied to the bounce and splat scales specified for this particle system." ); pList->AddTail( fxProp ); fxProp.SetupFloatMinMax( "PercentToBounce", 0.0f, 0.0f, 100.0f, eCurve_Linear, "Indicates the percentage of particles that should bounce when they impact a surface. This can range from 0 to 100 where 0 means none bounce, and 100 means all bounce." ); pList->AddTail( fxProp ); fxProp.SetupFloatMin( "BounceStrength", 0.75f, 0.0f, eCurve_None, "Specifies the amount of energy left when bouncing. 1 means an object will bounce as high as it was dropped, and 0 means it will not bounce at all" ); pList->AddTail( fxProp ); //------------------------------------------------------------ fxProp.SetupTextLine("Particle Splat"); pList->AddTail(fxProp); fxProp.SetupFloatMinMax( "SplatPercent", 0.0f, 0.0f, 100.0f, eCurve_Linear, "Indicates the percentage of particles that will create the impact effect named below when they impact a surface. This can range from 0 to 100 where 0 means none will create effects, and 100 means all will create effects." ); pList->AddTail( fxProp ); fxProp.SetupClientFXRef( "SplatEffect", "", eCurve_None, "The name of the impact effect to create when a particle impacts a surface."); pList->AddTail( fxProp ); }
/* * Prepare for projecting. */ void CPerspectiveProjection3D::Prepare(void) { FLOATmatrix3D t3dObjectStretch; // matrix for object stretch FLOATmatrix3D t3dObjectRotation; // matrix for object angles // calc. matrices for viewer and object angles and stretch MakeRotationMatrixFast( t3dObjectRotation, pr_ObjectPlacement.pl_OrientationAngle); MakeInverseRotationMatrixFast( pr_ViewerRotationMatrix, pr_ViewerPlacement.pl_OrientationAngle); t3dObjectStretch.Diagonal(pr_ObjectStretch); pr_vViewerPosition = pr_ViewerPlacement.pl_PositionVector; BOOL bXInverted = pr_ObjectStretch(1)<0; BOOL bYInverted = pr_ObjectStretch(2)<0; BOOL bZInverted = pr_ObjectStretch(3)<0; pr_bInverted = (bXInverted != bYInverted) != bZInverted; // if the projection is mirrored if (pr_bMirror) { // reflect viewer ReflectPositionVectorByPlane(pr_plMirror, pr_vViewerPosition); ReflectRotationMatrixByPlane_rows(pr_plMirror, pr_ViewerRotationMatrix); // get mirror plane in view space pr_plMirrorView = pr_plMirror; pr_plMirrorView -= pr_vViewerPosition; pr_plMirrorView *= pr_ViewerRotationMatrix; // invert inversion pr_bInverted = !pr_bInverted; } else if (pr_bWarp) { // get mirror plane in view space pr_plMirrorView = pr_plMirror; } // if the object is face-forward if (pr_bFaceForward) { // if it turns only heading if (pr_bHalfFaceForward) { // get the y-axis vector of object rotation FLOAT3D vY(t3dObjectRotation(1,2), t3dObjectRotation(2,2), t3dObjectRotation(3,2)); // find z axis of viewer FLOAT3D vViewerZ( pr_ViewerRotationMatrix(3,1), pr_ViewerRotationMatrix(3,2), pr_ViewerRotationMatrix(3,3)); // calculate x and z axis vectors to make object head towards viewer FLOAT3D vX = (-vViewerZ)*vY; vX.Normalize(); FLOAT3D vZ = vY*vX; // compose the rotation matrix back from those angles t3dObjectRotation(1,1) = vX(1); t3dObjectRotation(1,2) = vY(1); t3dObjectRotation(1,3) = vZ(1); t3dObjectRotation(2,1) = vX(2); t3dObjectRotation(2,2) = vY(2); t3dObjectRotation(2,3) = vZ(2); t3dObjectRotation(3,1) = vX(3); t3dObjectRotation(3,2) = vY(3); t3dObjectRotation(3,3) = vZ(3); // first apply object stretch then object rotation and then viewer rotation pr_mDirectionRotation = pr_ViewerRotationMatrix*t3dObjectRotation; pr_RotationMatrix = pr_mDirectionRotation*t3dObjectStretch; // if it is fully face forward } else { // apply object stretch and banking only FLOATmatrix3D mBanking; MakeRotationMatrixFast( mBanking, ANGLE3D(0,0, pr_ObjectPlacement.pl_OrientationAngle(3))); pr_mDirectionRotation = mBanking; pr_RotationMatrix = mBanking*t3dObjectStretch; } } else { // first apply object stretch then object rotation and then viewer rotation pr_mDirectionRotation = pr_ViewerRotationMatrix*t3dObjectRotation; pr_RotationMatrix = pr_mDirectionRotation*t3dObjectStretch; } // calc. offset of object from viewer pr_TranslationVector = pr_ObjectPlacement.pl_PositionVector - pr_vViewerPosition; // rotate offset only by viewer angles pr_TranslationVector = pr_TranslationVector*pr_ViewerRotationMatrix; // transform handle from object space to viewer space and add it to the offset pr_TranslationVector -= pr_vObjectHandle*pr_RotationMatrix; FLOAT2D vMin, vMax; // if using a shadow projection if (ppr_fMetersPerPixel>0) { // caclulate factors FLOAT fFactor = ppr_fViewerDistance/ppr_fMetersPerPixel; ppr_PerspectiveRatios(1) = -fFactor; ppr_PerspectiveRatios(2) = -fFactor; pr_ScreenCenter = -pr_ScreenBBox.Min(); vMin = pr_ScreenBBox.Min(); vMax = pr_ScreenBBox.Max(); // if using normal projection } else if (ppr_boxSubScreen.IsEmpty()) { // calculate perspective constants FLOAT2D v2dScreenSize = pr_ScreenBBox.Size(); pr_ScreenCenter = pr_ScreenBBox.Center(); /* calculate FOVHeight from FOVWidth by formula: halfanglej = atan( tan(halfanglei)*jsize*aspect/isize ) */ ANGLE aHalfI = ppr_FOVWidth/2; ANGLE aHalfJ = ATan(TanFast(aHalfI)*v2dScreenSize(2)*pr_AspectRatio/v2dScreenSize(1)); /* calc. perspective ratios by formulae: xratio = isize/(2*tan(anglei/2)) yratio = jsize/(2*tan(anglej/2)) sign is negative since viewer is looking down the -z axis */ ppr_PerspectiveRatios(1) = -v2dScreenSize(1)/(2.0f*TanFast(aHalfI))*pr_fViewStretch; ppr_PerspectiveRatios(2) = -v2dScreenSize(2)/(2.0f*TanFast(aHalfJ))*pr_fViewStretch; vMin = pr_ScreenBBox.Min()-pr_ScreenCenter; vMax = pr_ScreenBBox.Max()-pr_ScreenCenter; // if using sub-drawport projection } else { // calculate perspective constants FLOAT2D v2dScreenSize = pr_ScreenBBox.Size(); pr_ScreenCenter = pr_ScreenBBox.Center(); /* calculate FOVHeight from FOVWidth by formula: halfanglej = atan( tan(halfanglei)*jsize*aspect/isize ) */ ANGLE aHalfI = ppr_FOVWidth/2; ANGLE aHalfJ = ATan(TanFast(aHalfI)*v2dScreenSize(2)*pr_AspectRatio/v2dScreenSize(1)); /* calc. perspective ratios by formulae: xratio = isize/(2*tan(anglei/2)) yratio = jsize/(2*tan(anglej/2)) sign is negative since viewer is looking down the -z axis */ ppr_PerspectiveRatios(1) = -v2dScreenSize(1)/(2.0f*TanFast(aHalfI))*pr_fViewStretch; ppr_PerspectiveRatios(2) = -v2dScreenSize(2)/(2.0f*TanFast(aHalfJ))*pr_fViewStretch; vMin = ppr_boxSubScreen.Min()-pr_ScreenCenter; vMax = ppr_boxSubScreen.Max()-pr_ScreenCenter; pr_ScreenCenter -= ppr_boxSubScreen.Min(); } // find factors for left, right, up and down clipping FLOAT fMinI = vMin(1); FLOAT fMinJ = vMin(2); FLOAT fMaxI = vMax(1); FLOAT fMaxJ = vMax(2); FLOAT fRatioX = ppr_PerspectiveRatios(1); FLOAT fRatioY = ppr_PerspectiveRatios(2); #define MySgn(x) ((x)>=0?1:-1) FLOAT fDZ = -1.0f; FLOAT fDXL = fDZ*fMinI/fRatioX; FLOAT fDXR = fDZ*fMaxI/fRatioX; FLOAT fDYU = -fDZ*fMinJ/fRatioY; FLOAT fDYD = -fDZ*fMaxJ/fRatioY; FLOAT fNLX = -fDZ; FLOAT fNLZ = +fDXL; FLOAT fOoNL = 1.0f/(FLOAT)sqrt(fNLX*fNLX+fNLZ*fNLZ); fNLX*=fOoNL; fNLZ*=fOoNL; FLOAT fNRX = +fDZ; FLOAT fNRZ = -fDXR; FLOAT fOoNR = 1.0f/(FLOAT)sqrt(fNRX*fNRX+fNRZ*fNRZ); fNRX*=fOoNR; fNRZ*=fOoNR; FLOAT fNDY = -fDZ; FLOAT fNDZ = +fDYD; FLOAT fOoND = 1.0f/(FLOAT)sqrt(fNDY*fNDY+fNDZ*fNDZ); fNDY*=fOoND; fNDZ*=fOoND; FLOAT fNUY = +fDZ; FLOAT fNUZ = -fDYU; FLOAT fOoNU = 1.0f/(FLOAT)sqrt(fNUY*fNUY+fNUZ*fNUZ); fNUY*=fOoNU; fNUZ*=fOoNU; // make clip planes pr_plClipU = FLOATplane3D(FLOAT3D( 0,fNUY,fNUZ), 0.0f); pr_plClipD = FLOATplane3D(FLOAT3D( 0,fNDY,fNDZ), 0.0f); pr_plClipL = FLOATplane3D(FLOAT3D(fNLX, 0,fNLZ), 0.0f); pr_plClipR = FLOATplane3D(FLOAT3D(fNRX, 0,fNRZ), 0.0f); // mark as prepared pr_Prepared = TRUE; // calculate constant value used for calculating z-buffer k-value from vertex's z coordinate pr_fDepthBufferFactor = -pr_NearClipDistance; pr_fDepthBufferMul = pr_fDepthBufferFar-pr_fDepthBufferNear; pr_fDepthBufferAdd = pr_fDepthBufferNear; // calculate ratio for mip factor calculation ppr_fMipRatio = pr_ScreenBBox.Size()(1)/(ppr_PerspectiveRatios(1)*640.0f); }
void CAM_Render(CEntity *pen, CDrawPort *pdp) { if( cam_bRecord) { if (!_bInitialized) { _bInitialized = TRUE; SetSpeed(1.0f); _fStartTime = _pTimer->CurrentTick(); } FLOATmatrix3D m; MakeRotationMatrixFast(m, _cp.cp_aRot); FLOAT3D vX, vY, vZ; vX(1) = m(1,1); vX(2) = m(2,1); vX(3) = m(3,1); vY(1) = m(1,2); vY(2) = m(2,2); vY(3) = m(3,2); vZ(1) = m(1,3); vZ(2) = m(2,3); vZ(3) = m(3,3); _cp.cp_aRot(1)-=_pInput->GetAxisValue(MOUSE_X_AXIS)*0.5f; _cp.cp_aRot(2)-=_pInput->GetAxisValue(MOUSE_Y_AXIS)*0.5f; if( cam_bMoveForward) { _cp.cp_vPos -= vZ *cam_fSpeed; }; if( cam_bMoveBackward) { _cp.cp_vPos += vZ *cam_fSpeed; }; if( cam_bMoveLeft) { _cp.cp_vPos -= vX *cam_fSpeed; }; if( cam_bMoveRight) { _cp.cp_vPos += vX *cam_fSpeed; }; if( cam_bMoveUp) { _cp.cp_vPos += vY *cam_fSpeed; }; if( cam_bMoveDown) { _cp.cp_vPos -= vY *cam_fSpeed; }; if( cam_bTurnBankingLeft) { _cp.cp_aRot(3) += 10.0f; }; if( cam_bTurnBankingRight) { _cp.cp_aRot(3) -= 10.0f; }; if( cam_bZoomIn) { _cp.cp_aFOV -= 1.0f; }; if( cam_bZoomOut) { _cp.cp_aFOV += 1.0f; }; if( cam_bZoomDefault) { _cp.cp_aFOV = 90.0f; }; Clamp( _cp.cp_aFOV, 10.0f, 150.0f); if( cam_bResetToPlayer) { _cp.cp_vPos = pen->GetPlacement().pl_PositionVector; _cp.cp_aRot = pen->GetPlacement().pl_OrientationAngle; } if( cam_bSnapshot) { cam_bSnapshot = FALSE; WritePos(_cp); } } else { if (!_bInitialized) { _bInitialized = TRUE; ReadPos(_cp0); ReadPos(_cp1); SetSpeed(_cp0.cp_fSpeed); _fStartTime = _pTimer->CurrentTick(); } TIME tmNow = _pTimer->GetLerpedCurrentTick()-_fStartTime; if (tmNow>_cp1.cp_tmTick) { _cp0 = _cp1; ReadPos(_cp1); SetSpeed(_cp0.cp_fSpeed); } FLOAT fRatio = (tmNow-_cp0.cp_tmTick)/(_cp1.cp_tmTick-_cp0.cp_tmTick); _cp.cp_vPos = Lerp(_cp0.cp_vPos, _cp1.cp_vPos, fRatio); _cp.cp_aRot = Lerp(_cp0.cp_aRot, _cp1.cp_aRot, fRatio); _cp.cp_aFOV = Lerp(_cp0.cp_aFOV, _cp1.cp_aFOV, fRatio); } CPlacement3D plCamera; plCamera.pl_PositionVector = _cp.cp_vPos; plCamera.pl_OrientationAngle = _cp.cp_aRot; // init projection parameters CPerspectiveProjection3D prPerspectiveProjection; prPerspectiveProjection.FOVL() = _cp.cp_aFOV; prPerspectiveProjection.ScreenBBoxL() = FLOATaabbox2D( FLOAT2D(0.0f, 0.0f), FLOAT2D((float)pdp->GetWidth(), (float)pdp->GetHeight()) ); prPerspectiveProjection.AspectRatioL() = 1.0f; prPerspectiveProjection.FrontClipDistanceL() = 0.3f; CAnyProjection3D prProjection; prProjection = prPerspectiveProjection; // set up viewer position prProjection->ViewerPlacementL() = plCamera; // render the view RenderView(*pen->en_pwoWorld, *(CEntity*)NULL, prProjection, *pdp); }