예제 #1
0
// 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;
}
예제 #2
0
파일: xmatrix.cpp 프로젝트: astrobit/xlibs
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();
	}
}
예제 #3
0
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;
}
예제 #4
0
// 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;
}
예제 #5
0
파일: xmatrix.cpp 프로젝트: astrobit/xlibs
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;
}
예제 #6
0
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++;
	}
}
예제 #8
0
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);
}
예제 #10
0
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);
}