void CoreCircleCollider_Imp::Update() {

		if (ownerObject == nullptr) {
			return;
		}

		auto matrix = ownerObject->GetAbsoluteMatrixToTransform();

		auto vc = Vector3DF(center.X, center.Y, 1);
		auto res1 = matrix * vc;
		auto tcenter = Vector2DF(res1.X, res1.Y);

		auto vr = Vector3DF(center.X + radius, center.Y, 1);
		auto res2 = matrix * vr;
		auto tradpos = Vector2DF(res2.X, res2.Y);
		auto tradius = (tcenter - tradpos).GetLength();

		aabb.X = tcenter.X - tradius;
		aabb.Y = tcenter.Y - tradius;
		aabb.Width = aabb.Height = tradius * 2;

		b2circleShape.m_p = b2Vec2(tcenter.X, tcenter.Y);
		b2circleShape.m_radius = tradius;

		coreCollision2DManager->NotifyLastTransformed(this);
	}
void init ()
{
	
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);	
	glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);	

	srand ( time ( 0x0 ) );

	glClearColor( 0.49, 0.49, 0.49, 1.0 );
	glShadeModel( GL_SMOOTH );

	glEnable ( GL_COLOR_MATERIAL );
	glEnable (GL_DEPTH_TEST);  
	glEnable (GL_BLEND);
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
	glDepthMask ( 1 );
	glEnable ( GL_TEXTURE_2D );

	// callbacks
	glutDisplayFunc( display );
	glutReshapeFunc( reshape );
	glutKeyboardFunc( keyboard_func );
	glutMouseFunc( mouse_click_func );  
	glutMotionFunc( mouse_move_func );
	glutIdleFunc( idle_func );
	glutSetCursor ( GLUT_CURSOR_NONE );

	cam_angs.x = 29;		cam_angs.y = 75;		cam_angs.z = 80.0;
	cam_to.x = 0;		cam_to.y = 0;		cam_to.z = 5;
	cam_fov = 35.0;

	light[0].x = 39;		light[0].y = -60;	light[0].z = 43;
	light_to[0].x = 0;	light_to[0].y = 0;	light_to[0].z = 0;

	light[1].x = 15;		light[1].y = -5;	light[1].z = 145;	
	light_to[1].x = 0;	light_to[1].y = 0;	light_to[1].z = 0;  

	light_fov = 45;

	#ifdef USE_SHADOWS
		createShadowTextures();
		createFrameBuffer ();
		setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
		setShadowLightColor ( .7, .7, .7, 0.2, 0.2, 0.2 );		
	#endif

	obj_from.x = 0;		obj_from.y = 0;		obj_from.z = 20;		// emitter
	obj_angs.x = 118.7;	obj_angs.y = 200;	obj_angs.z = 1.0;
	obj_dang.x = 1;	obj_dang.y = 1;		obj_dang.z = 0;

	psys.Initialize ( BFLUID, psys_nmax );
	psys.SPH_CreateExample ( 0, psys_nmax );
	psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
	psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );

	psys.SetParam ( PNT_DRAWMODE, int(bPntDraw ? 1:0) );
	psys.SetParam ( CLR_MODE, iClrMode );	
}
	Vector3DF MaterialPropertyBlock_Imp::GetVector3DF(const achar* name)
	{
		if (values.count(name) > 0)
		{
			if (values[name].ValueType != ShaderVariableType::Vector3DF) return Vector3DF(0.0f, 0.0f, 0.0f);
			return Vector3DF(values[name].Data.Float4[0], values[name].Data.Float4[1], values[name].Data.Float4[2]);
		}
		return Vector3DF(0.0f, 0.0f, 0.0f);
	}
	ObjectInternal::ObjectInternal()
		: userData(NULL)
		, world(NULL)
		, ObjectIndex(-1)
	{
		currentStatus.Position = Vector3DF();
		currentStatus.radius = 0.0f;
		currentStatus.Type = OBJECT_SHAPE_TYPE_NONE;

		nextStatus.Position = Vector3DF();
		nextStatus.radius = 0.0f;
		nextStatus.Type = OBJECT_SHAPE_TYPE_NONE;
	}
Beispiel #5
0
void init ()
{
	srand ( time ( 0x0 ) );
	
  obj_from.x = 0;		obj_from.y = 0;		obj_from.z = 20;		// emitter
	obj_angs.x = 118.7;	obj_angs.y = 200;	obj_angs.z = 1.0;

	psys.Initialize ( BFLUID, psys_nmax );
	psys.SPH_CreateExample ( 0, psys_nmax );
	psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
	psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );

	psys.SetParam ( PNT_DRAWMODE, int(bPntDraw ? 1:0) );
	psys.SetParam ( CLR_MODE, iClrMode );	
}
float PointSet::GetValue ( float x, float y, float z )
{
	float dx, dy, dz, dsq;
	float sum;
	int pndx;
	Point* pcurr;
	float R2 = 1.8*1.8;

	Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );

	int cnt = 0;
	sum = 0.0;
	for (int cell=0; cell < 8; cell++ ) {
		if ( m_GridCell[cell] != -1 ) {
			pndx = m_Grid [ m_GridCell[cell] ];
			while ( pndx != -1 ) {					
				pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
				dx = x - pcurr->pos.x;
				dy = y - pcurr->pos.y;
				dz = z - pcurr->pos.z;
				dsq = dx*dx+dy*dy+dz*dz;		
				if ( dsq < R2 ) sum += R2 / dsq;
				pndx = pcurr->next;
			}	
		}
	}
	return sum;	
}	
	void CoreRectangleCollider_Imp::Update() {

		if (ownerObject == nullptr) {
			return;
		}

		auto vertexes = area.GetVertexes();

		std::vector<b2Vec2> polyPoints;
		culling2d::Vector2DF minPos = culling2d::Vector2DF(FLT_MAX, FLT_MAX);
		culling2d::Vector2DF maxPos = culling2d::Vector2DF(FLT_MIN, FLT_MIN);

		auto matrix = ownerObject->GetAbsoluteMatrixToTransform();
		for (auto vertex : vertexes)
		{

			auto vc = Vector3DF(vertex.X, vertex.Y, 1);
			auto res1 = matrix * vc;
			auto pos = Vector2DF(res1.X, res1.Y);

			polyPoints.push_back(b2Vec2(pos.X, pos.Y));
			minPos.X = Min(minPos.X, pos.X);
			minPos.Y = Min(minPos.Y, pos.Y);
			maxPos.X = Max(maxPos.X, pos.X);
			maxPos.Y = Max(maxPos.Y, pos.Y);
		}
		aabb.X = minPos.X;
		aabb.Y = minPos.Y;
		aabb.Width = maxPos.X - minPos.X;
		aabb.Height = maxPos.Y - minPos.Y;

		b2polygonShape.Set(polyPoints.data(), polyPoints.size());

		coreCollision2DManager->NotifyLastTransformed(this);
	}
Beispiel #8
0
// This function called by both OpenGL (GLUT) and DirectX
void mouse_drag_func ( int x, int y )
{
	if ( guiMouseDrag ( x, y ) ) return;	// event handling for nv2D GUIs

	int dx = x - last_x;
	int dy = y - last_y;

	float deltx = window_width / cam.getToPos().z;
	float delty = window_height / cam.getToPos().z;
	
	// Camera interaction
	int mode = 0;
	switch ( mode ) {
	case 0:
		if ( dragging == DRAG_LEFT ) {
			glide += Vector3DF( dx / cam.getToPos().z, 0, 0);		
			cam.moveToPos ( 0, dy, 0 );
		} else if ( dragging == DRAG_RIGHT ) {	
			cam.moveToPos ( 0, 0, -dy*0.001 );
			if ( cam.to_pos.z < 0.001 ) cam.to_pos.z = 0.001;
		}
		break;	
	}
	last_x = x;
	last_y = y;
}
Beispiel #9
0
void Camera3D::setAngles ( float ax, float ay, float az )
{
	ang_euler = Vector3DF(ax,ay,az);
	to_pos.x = from_pos.x - cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) * mDolly;
	to_pos.y = from_pos.y - sin ( ang_euler.y * DEGtoRAD ) * mDolly;
	to_pos.z = from_pos.z - cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD ) * mDolly;
	updateMatricies ();
}
	void CoreGeometryObject2D_Imp::Draw(Renderer2D* renderer)
	{
		if (!GetAbsoluteBeingDrawn() || !GetIsAlive() || m_shape == nullptr)
		{
			return;
		}

		auto shape_Imp = CoreShape2DToImp(m_shape);

		auto& triangles = shape_Imp->GetDividedTriangles();

		if (triangles.size() == 0)
		{
			auto layer = GetLayer();
			auto g = (Graphics_Imp*)layer->GetGraphicsImp();
			g->GetLog()->Write("無効な形状を描画しました。正しく表示されない場合があります。", LogLevel::Warning);
		}

		for (auto triangle : triangles)
		{
			std::array<Vector2DF, 4> position;
			std::array<Vector2DF, 4> uvs;

			for (int i = 0; i < 3; ++i)
			{
				position[i] = triangle->GetPointByIndex(i);
				uvs[i] = triangle->GetUVByIndex(i);
			}
			position[3] = position[2];
			uvs[3] = uvs[2];

			auto matrix = GetAbsoluteMatrixToTransform();
			for (auto& pos : position)
			{
				pos -= centerPosition;
				auto v3 = Vector3DF(pos.X, pos.Y, 1);
				auto result = matrix * v3;
				pos = Vector2DF(result.X, result.Y);
			}

			Color color[4];
			auto col = GetAbsoluteColor();
			color[0] = col;
			color[1] = col;
			color[2] = col;
			color[3] = col;

			renderer->AddSprite(
				position.data(),
				color,
				uvs.data(),
				(m_shape->GetShapeType() == ShapeType::LineShape) ? nullptr : m_texture,
				alphaBlendMode,
				GetAbsoluteDrawingPriority(),
				m_textureFilterType);
		}
	}
Beispiel #11
0
void Camera3D::updateMatricies ()
{
	Matrix4F basis;
	Vector3DF temp;	
	
	// compute camera direction vectors	--- MATCHES OpenGL's gluLookAt function (DO NOT MODIFY)
	dir_vec = to_pos;					// f vector in gluLookAt docs						
	dir_vec -= from_pos;				// eye = from_pos in gluLookAt docs
	dir_vec.Normalize ();
	side_vec = dir_vec;
	side_vec.Cross ( up_dir );
	side_vec.Normalize ();
	up_vec = side_vec;
	up_vec.Cross ( dir_vec );
	up_vec.Normalize();
	dir_vec *= -1;
	
	// construct view matrix
	rotate_matrix.Basis (side_vec, up_vec, dir_vec );
	view_matrix = rotate_matrix;
	//Matrix4F trans;
	//trans.Translate ( -from_pos.x, -from_pos.y, -from_pos.z );		// !efficiency
	view_matrix.PreTranslate ( Vector3DF(-from_pos.x, -from_pos.y, -from_pos.z ) );

	// construct projection matrix  --- MATCHES OpenGL's gluPerspective function (DO NOT MODIFY)
	float sx = tan ( mFov * 0.5 * DEGtoRAD ) * mNear;
	float sy = sx / mAspect;
	proj_matrix = 0.0;
	proj_matrix(0,0) = 2.0*mNear / sx;				// matches OpenGL definition
	proj_matrix(1,1) = 2.0*mNear / sy;
	proj_matrix(2,2) = -(mFar + mNear)/(mFar - mNear);			// C
	proj_matrix(2,3) = -(2.0*mFar * mNear)/(mFar - mNear);		// D
	proj_matrix(3,2) = -1.0;

	// construct tile projection matrix --- MATCHES OpenGL's glFrustum function (DO NOT MODIFY) 
	float l, r, t, b;
	l = -sx + 2.0*sx*mTile.x;						// Tile is in range 0 <= x,y <= 1
	r = -sx + 2.0*sx*mTile.z;
	t =  sy - 2.0*sy*mTile.y;
	b =  sy - 2.0*sy*mTile.w;
	tileproj_matrix = 0.0;
	tileproj_matrix(0,0) = 2.0*mNear / (r - l);
	tileproj_matrix(1,1) = 2.0*mNear / (t - b);
	tileproj_matrix(0,2) = (r + l) / (r - l);		// A
	tileproj_matrix(1,2) = (t + b) / (t - b);		// B
	tileproj_matrix(2,2) = proj_matrix(2,2);		// C
	tileproj_matrix(2,3) = proj_matrix(2,3);		// D
	tileproj_matrix(3,2) = -1.0;

	// construct inverse rotate and inverse projection matrix
    Vector3DF tvz(0, 0, 0);
	//invrot_matrix.InverseView ( rotate_matrix.GetDataF(), Vector3DF(0,0,0) );		// Computed using rule: "Inverse of a basis rotation matrix is its transpose." (So long as translation is taken out)
	invrot_matrix.InverseView ( rotate_matrix.GetDataF(), tvz );		// Computed using rule: "Inverse of a basis rotation matrix is its transpose." (So long as translation is taken out)
	invproj_matrix.InverseProj ( tileproj_matrix.GetDataF() );							// Computed using rule: 

	updateFrustum ();
}
Beispiel #12
0
Vector3DF getClr ( unsigned long id )
{
	srand ( id );	
	for (int n=0; n < 256; n++ ) {
		if ( n % 64 == 0 ) srand( rand() );
		rand();
	}
	return Vector3DF(float(rand())/RAND_MAX, float(rand())/RAND_MAX, float(rand())/RAND_MAX );
}
	void RenderedCameraObject3DProxy::OnUpdateAsync()
	{
		if (deviceType == GraphicsDeviceType::DirectX11)
		{
			ProjectionMatrix.SetPerspectiveFovRH(
				FOV / 180.0f * 3.141592f,
				(float) WindowSize.X / (float) WindowSize.Y,
				ZNear,
				ZFar);
		}
		else
		{
			ProjectionMatrix.SetPerspectiveFovRH_OpenGL(
				FOV / 180.0f * 3.141592f,
				(float) WindowSize.X / (float) WindowSize.Y,
				ZNear,
				ZFar);
		}

		auto pos = GetGlobalPosition();
		CameraMatrix.SetLookAtRH(
			pos,
			Focus,
			Vector3DF(0, 1, 0));

		
		auto invCameraMat = (CameraMatrix).GetInverted();

		auto fov = FOV / 180.0f * 3.141592f;
		auto aspect = (float)WindowSize.X / (float)WindowSize.Y;

		float yScale = 1 / tanf(fov / 2);
		float xScale = yScale / aspect;

		ReconstructInfo1 = Vector3DF(ZNear * ZFar, ZFar - ZNear, -ZFar);
		//ReconstructInfo1 = Vector3DF(cP->ZFar - cP->ZNear, cP->ZNear, 0.0f);
		ReconstructInfo2 = Vector4DF(1.0f / xScale, 1.0f / yScale, 0.0f, 0.0f);

		Vector3DF zero;
		zero = CameraMatrix.Transform3D(zero);
		UpDir = CameraMatrix.Transform3D(Vector3DF(0, 1, 0)) - zero;
		RightDir = CameraMatrix.Transform3D(Vector3DF(1, 0, 0)) - zero;
		FrontDir = CameraMatrix.Transform3D(Vector3DF(0, 0, 1)) - zero;		
	}
	RenderedCameraObject3DProxy::RenderedCameraObject3DProxy(Graphics* graphics)
	{
		deviceType = graphics->GetGraphicsDeviceType();
		m_postEffectRenderer = PostEffectRenderer::Create(graphics);

		m_renderTarget_FR[0] = nullptr;
		m_renderTarget_FR[1] = nullptr;

		Up = Vector3DF(0, 1, 0);
	}
Beispiel #15
0
void Camera3D::moveToPos ( float tx, float ty, float tz )
{
	to_pos += Vector3DF(tx,ty,tz);

	float dx, dy, dz;
	dx = cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) ;
	dy = sin ( ang_euler.y * DEGtoRAD );
	dz = cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD );
	from_pos.x = to_pos.x + dx * mOrbitDist;
	from_pos.y = to_pos.y + dy * mOrbitDist;
	from_pos.z = to_pos.z + dz * mOrbitDist;
	updateMatricies ();
}
Beispiel #16
0
void Camera3D::moveOrbit ( float ax, float ay, float az, float dd )
{
	ang_euler += Vector3DF(ax,ay,az);
	mOrbitDist += dd;
	
	float dx, dy, dz;
	dx = cos ( ang_euler.y * DEGtoRAD ) * sin ( ang_euler.x * DEGtoRAD ) ;
	dy = sin ( ang_euler.y * DEGtoRAD );
	dz = cos ( ang_euler.y * DEGtoRAD ) * cos ( ang_euler.x * DEGtoRAD );
	from_pos.x = to_pos.x + dx * mOrbitDist;
	from_pos.y = to_pos.y + dy * mOrbitDist;
	from_pos.z = to_pos.z + dz * mOrbitDist;
	updateMatricies ();
}
	void CoreGeometryObject2D_Imp::CalculateBoundingCircle()
	{
		auto shape_Imp = CoreShape2DToImp(m_shape);
		if (shape_Imp == nullptr)
		{
			m_boundingCircle = culling2d::Circle(culling2d::Vector2DF(), 0);
			return;
		}

		m_boundingCircle = shape_Imp->GetBoundingCircle();

		std::array<Vector2DF, 4> position;

		auto p1 = m_boundingCircle.Position - culling2d::Vector2DF(m_boundingCircle.Radius, 0);
		position[0] = Vector2DF(p1.X, p1.Y);

		auto p2 = m_boundingCircle.Position + culling2d::Vector2DF(m_boundingCircle.Radius, 0);
		position[1] = Vector2DF(p2.X, p2.Y);

		auto p3 = m_boundingCircle.Position - culling2d::Vector2DF(0, m_boundingCircle.Radius);
		position[2] = Vector2DF(p3.X, p3.Y);

		auto p4 = m_boundingCircle.Position + culling2d::Vector2DF(0, m_boundingCircle.Radius);
		position[3] = Vector2DF(p4.X, p4.Y);

		auto parentMatrix = GetParentsMatrix();
		auto matrix = GetMatrixToTransform();

		Vector2DF sum = Vector2DF();
		for (auto& pos : position)
		{
			pos -= centerPosition;
			auto v3 = Vector3DF(pos.X, pos.Y, 1);
			auto result = parentMatrix * matrix * v3;
			pos = Vector2DF(result.X, result.Y);
			sum += pos;
		}

		auto c = sum / 4.0f;
		auto r = 0.0f;

		for (auto& pos : position)
		{
			r = Max(r, (pos - c).GetLength());
		}

		m_boundingCircle = culling2d::Circle(culling2d::Vector2DF(c.X, c.Y), r);
	}
Vector3DF Vector3DF::HSVtoRGB ()
{
	double m, n, f;
	int i = floor ( x*6.0 );
	f = x*6.0 - i;
	if ( i % 2 == 0 ) f = 1.0 - f;	
	m = z * (1.0 - y );
	n = z * (1.0 - y * f );	
	switch ( i ) {
	case 6: 
	case 0: return Vector3DF( z, n, m );	break;
	case 1: return Vector3DF( n, z, m );	break;
	case 2: return Vector3DF( m, z, n );	break;
	case 3: return Vector3DF( m, n, z );	break;
	case 4: return Vector3DF( n, m, z );	break;
	case 5: return Vector3DF( z, m, n );	break;
	};
	return Vector3DF(1,1,1);
}
Vector3DF Vector3DF::RGBtoHSV ()
{
	float h,s,v;
	float minv, maxv;
	int i;
	float f;

	minv = min3(x, y, z);
	maxv = max3(x, y, z);
	if (minv==maxv) {
		v = (float) maxv;
		h = 0.0; 
		s = 0.0;			
	} else {
		v = (float) maxv;
		s = (maxv - minv) / maxv;
		f = (x == minv) ? y - z : ((y == minv) ? z - x : x - y); 	
		i = (x == minv) ? 3 : ((y == minv) ? 5 : 1);
		h = (i - f / (maxv - minv) ) / 6.0f;	
	}
	return Vector3DF(h,s,v);
}
Vector3DF PointSet::GetGradient ( float x, float y, float z )
{
	Vector3DF norm;  
	float dx, dy, dz, dsq;
	float sum;
	int pndx;
	Point* pcurr;
	float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0);

	Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );

	int cnt = 0;
	sum = 0.0;
	norm.Set (0,0,0);
	for (int cell=0; cell < 8; cell++ ) {
		if ( m_GridCell[cell] != -1 ) {
			pndx = m_Grid [ m_GridCell[cell] ];
			while ( pndx != -1 ) {					
				pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
				dx = x - pcurr->pos.x;
				dy = y - pcurr->pos.y;
				dz = z - pcurr->pos.z;
				dsq = dx*dx+dy*dy+dz*dz;				
				if ( dsq > 0 && dsq < R2 ) {
					dsq = 2.0*R2 / (dsq*dsq);
					norm.x += dx * dsq;
					norm.y += dy * dsq;
					norm.z += dz * dsq;						
				}
				pndx = pcurr->next;
			}	
		}
	}
	norm.Normalize ();	
	return norm;
}
DWORD PointSet::GetColor ( float x, float y, float z )
{
	Vector3DF clr;  
	float dx, dy, dz, dsq;
	float sum;
	int pndx;
	Point* pcurr;
	float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0);

	Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );

	int cnt = 0;
	sum = 0.0;
	clr.Set (0,0,0);
	for (int cell=0; cell < 8; cell++ ) {
		if ( m_GridCell[cell] != -1 ) {
			pndx = m_Grid [ m_GridCell[cell] ];
			while ( pndx != -1 ) {					
				pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
				dx = x - pcurr->pos.x;
				dy = y - pcurr->pos.y;
				dz = z - pcurr->pos.z;
				dsq = dx*dx+dy*dy+dz*dz;				
				if ( dsq < R2 ) {
					dsq = 2.0*R2 / (dsq*dsq);					
					clr.x += RED(pcurr->clr) * dsq;
					clr.y += GRN(pcurr->clr) * dsq;
					clr.z += BLUE(pcurr->clr) * dsq;						
				}
				pndx = pcurr->next;
			}	
		}
	}
	clr.Normalize ();
	return COLORA(clr.x, clr.y, clr.z, 1.0);
}
Beispiel #22
0
Camera3D::Camera3D ()
{	
	
	mProjType = Perspective;
	mWire = 0;

	up_dir.Set ( 0.0, 1.0, 0 );				// frustum params
	mAspect = 800/600.0;
	mDolly = 5.0;
	mFov = 40.0;	
	mNear = 0.1;
	mFar = 6000.0;
	mTile.Set ( 0, 0, 1, 1 );

	for (int n=0; n < 8; n++ ) mOps[n] = false;	
	mOps[0] = false;

//	mOps[0] = true;		
//	mOps[1] = true;

	setOrbit ( 0, 45, 0, Vector3DF(0,0,0), 120.0, 5.0 );
	updateMatricies ();

}
Beispiel #23
0
	Matrix44 ModelUtils::CalcRotationMatrix(float rotation[4], RotationOrder rotationType)
	{
		if (rotationType == RotationOrder::QUATERNION)
		{
			Matrix44 matR;
			matR.SetQuaternion(rotation[0], rotation[1], rotation[2], rotation[3]);
			return matR;
		}
		else if (rotationType == RotationOrder::AXIS)
		{
			Matrix44 matR;
			matR.SetRotationAxis(Vector3DF(rotation[0], rotation[2], -rotation[1]), rotation[3]);
			return matR;
		}
		else
		{
			Matrix44 mat, matRx, matRy, matRz;
			matRx.SetRotationX(rotation[0]);
			matRy.SetRotationY(rotation[1]);
			matRz.SetRotationZ(rotation[2]);

			if (rotationType == RotationOrder::XZY)
			{
				mat = Matrix44::Mul(mat, matRz, matRx);
				mat = Matrix44::Mul(mat, matRy, mat);
			}

			if (rotationType == RotationOrder::XYZ)
			{
				mat = Matrix44::Mul(mat, matRy, matRx);
				mat = Matrix44::Mul(mat, matRz, mat);
			}

			if (rotationType == RotationOrder::ZXY)
			{
				mat = Matrix44::Mul(mat, matRx, matRz);
				mat = Matrix44::Mul(mat, matRy, mat);
			}

			if (rotationType == RotationOrder::ZYX)
			{
				mat = Matrix44::Mul(mat, matRy, matRz);
				mat = Matrix44::Mul(mat, matRz, mat);
			}

			if (rotationType == RotationOrder::YXZ)
			{
				mat = Matrix44::Mul(mat, matRx, matRy);
				mat = Matrix44::Mul(mat, matRz, mat);
			}

			if (rotationType == RotationOrder::YZX)
			{
				mat = Matrix44::Mul(mat, matRz, matRy);
				mat = Matrix44::Mul(mat, matRx, mat);
			}

			return mat;
		}

		return Matrix44();
	}
	void WorldInternal::Culling(const Matrix44& cameraProjMat, bool isOpenGL)
	{
		objs.clear();
	
#ifdef _WIN32
		if (_finite(cameraProjMat.Values[2][2]) != 0 &&
			cameraProjMat.Values[0][0] != 0.0f &&
			cameraProjMat.Values[1][1] != 0.0f)
		{
#else
		
		if (isfinite(cameraProjMat.Values[2][2]) != 0 &&
			cameraProjMat.Values[0][0] != 0.0f &&
			cameraProjMat.Values[1][1] != 0.0f)
		{
#endif
			Matrix44 cameraProjMatInv = cameraProjMat;
			cameraProjMatInv.SetInverted();

			float maxx = 1.0f;
			float minx = -1.0f;

			float maxy = 1.0f;
			float miny = -1.0f;

			float maxz = 1.0f;
			float minz = 0.0f;
			if (isOpenGL) minz = -1.0f;

			Vector3DF eyebox[8];

			eyebox[0 + 0] = Vector3DF(minx, miny, maxz);
			eyebox[1 + 0] = Vector3DF(maxx, miny, maxz);
			eyebox[2 + 0] = Vector3DF(minx, maxy, maxz);
			eyebox[3 + 0] = Vector3DF(maxx, maxy, maxz);

			eyebox[0 + 4] = Vector3DF(minx, miny, minz);
			eyebox[1 + 4] = Vector3DF(maxx, miny, minz);
			eyebox[2 + 4] = Vector3DF(minx, maxy, minz);
			eyebox[3 + 4] = Vector3DF(maxx, maxy, minz);

			for (int32_t i = 0; i < 8; i++)
			{
				eyebox[i] = cameraProjMatInv.Transform3D(eyebox[i]);
			}

			// 0-right 1-left 2-top 3-bottom 4-front 5-back
			Vector3DF facePositions[6];
			facePositions[0] = eyebox[5];
			facePositions[1] = eyebox[4];
			facePositions[2] = eyebox[6];
			facePositions[3] = eyebox[4];
			facePositions[4] = eyebox[4];
			facePositions[5] = eyebox[0];

			Vector3DF faceDir[6];
			faceDir[0] = Vector3DF::Cross(eyebox[1] - eyebox[5], eyebox[7] - eyebox[5]);
			faceDir[1] = Vector3DF::Cross(eyebox[6] - eyebox[4], eyebox[0] - eyebox[4]);

			faceDir[2] = Vector3DF::Cross(eyebox[7] - eyebox[6], eyebox[2] - eyebox[6]);
			faceDir[3] = Vector3DF::Cross(eyebox[0] - eyebox[4], eyebox[5] - eyebox[4]);

			faceDir[4] = Vector3DF::Cross(eyebox[5] - eyebox[4], eyebox[6] - eyebox[4]);
			faceDir[5] = Vector3DF::Cross(eyebox[2] - eyebox[0], eyebox[1] - eyebox[5]);

			for (int32_t i = 0; i < 6; i++)
			{
				faceDir[i].Normalize();
			}

			for (int32_t z = 0; z < viewCullingZDiv; z++)
			{
				for (int32_t y = 0; y < viewCullingYDiv; y++)
				{
					for (int32_t x = 0; x < viewCullingXDiv; x++)
					{
						Vector3DF eyebox_[8];

						float xsize = 1.0f / (float) viewCullingXDiv;
						float ysize = 1.0f / (float) viewCullingYDiv;
						float zsize = 1.0f / (float) viewCullingZDiv;

						for (int32_t e = 0; e < 8; e++)
						{
							float x_, y_, z_;
							if (e == 0){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * z; }
							if (e == 1){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * z; }
							if (e == 2){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * z; }
							if (e == 3){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * z; }
							if (e == 4){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * (z + 1); }
							if (e == 5){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * (z + 1); }
							if (e == 6){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * (z + 1); }
							if (e == 7){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * (z + 1); }

							Vector3DF yzMid[4];
							yzMid[0] = eyebox[0] * x_ + eyebox[1] * (1.0f - x_);
							yzMid[1] = eyebox[2] * x_ + eyebox[3] * (1.0f - x_);
							yzMid[2] = eyebox[4] * x_ + eyebox[5] * (1.0f - x_);
							yzMid[3] = eyebox[6] * x_ + eyebox[7] * (1.0f - x_);

							Vector3DF zMid[2];
							zMid[0] = yzMid[0] * y_ + yzMid[1] * (1.0f - y_);
							zMid[1] = yzMid[2] * y_ + yzMid[3] * (1.0f - y_);

							eyebox_[e] = zMid[0] * z_ + zMid[1] * (1.0f - z_);
						}



						Vector3DF max_(-FLT_MAX, -FLT_MAX, -FLT_MAX);
						Vector3DF min_(FLT_MAX, FLT_MAX, FLT_MAX);

						for (int32_t i = 0; i < 8; i++)
						{
							if (eyebox_[i].X > max_.X) max_.X = eyebox_[i].X;
							if (eyebox_[i].Y > max_.Y) max_.Y = eyebox_[i].Y;
							if (eyebox_[i].Z > max_.Z) max_.Z = eyebox_[i].Z;

							if (eyebox_[i].X < min_.X) min_.X = eyebox_[i].X;
							if (eyebox_[i].Y < min_.Y) min_.Y = eyebox_[i].Y;
							if (eyebox_[i].Z < min_.Z) min_.Z = eyebox_[i].Z;
						}

						/* 範囲内に含まれるグリッドを取得 */
						for (size_t i = 0; i < layers.size(); i++)
						{
							layers[i]->AddGrids(max_, min_, grids);
						}
					}
				}
			}

			/* 外領域追加 */
			grids.push_back(&outofLayers);
			grids.push_back(&allLayers);

			/* グリッドからオブジェクト取得 */
			for (size_t i = 0; i < grids.size(); i++)
			{
				for (size_t j = 0; j < grids[i]->GetObjects().size(); j++)
				{
					Object* o = grids[i]->GetObjects()[j];
					ObjectInternal* o_ = (ObjectInternal*) o;

					if (
						o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL ||
						IsInView(o_->GetPosition(), o_->GetNextStatus().CalcRadius(), facePositions, faceDir))
					{
						objs.push_back(o);
					}
				}
			}

			/* 取得したグリッドを破棄 */
			for (size_t i = 0; i < grids.size(); i++)
			{
				grids[i]->IsScanned = false;
			}

			grids.clear();
		}
		else
		{
			grids.push_back(&allLayers);

			/* グリッドからオブジェクト取得 */
			for (size_t i = 0; i < grids.size(); i++)
			{
				for (size_t j = 0; j < grids[i]->GetObjects().size(); j++)
				{
					Object* o = grids[i]->GetObjects()[j];
					ObjectInternal* o_ = (ObjectInternal*) o;

					if (o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL)
					{
						objs.push_back(o);
					}
				}
			}

			/* 取得したグリッドを破棄 */
			for (size_t i = 0; i < grids.size(); i++)
			{
				grids[i]->IsScanned = false;
			}

			grids.clear();
		}
		
	}

	bool WorldInternal::Reassign()
	{
		/* 数が少ない */
		if (outofLayers.GetObjects().size() < 10) return false;

		objs.clear();

		for (size_t i = 0; i < layers.size(); i++)
		{
			delete layers[i];
		}

		layers.clear();
		outofLayers.GetObjects().clear();
		allLayers.GetObjects().clear();

		outofLayers.IsScanned = false;
		allLayers.IsScanned = false;

		for (auto& it : containedObjects)
		{
			auto o = (ObjectInternal*) (it);
			o->ObjectIndex = -1;
		}

		float xmin = FLT_MAX;
		float xmax = -FLT_MAX;
		float ymin = FLT_MAX;
		float ymax = -FLT_MAX;
		float zmin = FLT_MAX;
		float zmax = -FLT_MAX;

		for (auto& it : containedObjects)
		{
			ObjectInternal* o_ = (ObjectInternal*) it;
			if (o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL) continue;

			if (xmin > o_->GetNextStatus().Position.X) xmin = o_->GetNextStatus().Position.X;
			if (xmax < o_->GetNextStatus().Position.X) xmax = o_->GetNextStatus().Position.X;
			if (ymin > o_->GetNextStatus().Position.Y) ymin = o_->GetNextStatus().Position.Y;
			if (ymax < o_->GetNextStatus().Position.Y) ymax = o_->GetNextStatus().Position.Y;
			if (zmin > o_->GetNextStatus().Position.Z) zmin = o_->GetNextStatus().Position.Z;
			if (zmax < o_->GetNextStatus().Position.Z) zmax = o_->GetNextStatus().Position.Z;

		}

		auto xlen = Max(abs(xmax), abs(xmin)) * 2.0f;
		auto ylen = Max(abs(ymax), abs(ymin)) * 2.0f;
		auto zlen = Max(abs(zmax), abs(zmin)) * 2.0f;

		WorldInternal(xlen, ylen, zlen, this->layerCount);

		for (auto& it: containedObjects)
		{
			ObjectInternal* o_ = (ObjectInternal*) (it);
			AddObjectInternal(o_);
		}
		return true;
	}

	void WorldInternal::Dump(const char* path, const Matrix44& cameraProjMat, bool isOpenGL)
	{
		std::ofstream ofs(path);

		/* カメラ情報出力 */
		Matrix44 cameraProjMatInv = cameraProjMat;
		cameraProjMatInv.SetInverted();

		float maxx = 1.0f;
		float minx = -1.0f;

		float maxy = 1.0f;
		float miny = -1.0f;

		float maxz = 1.0f;
		float minz = 0.0f;
		if (isOpenGL) minz = -1.0f;

		Vector3DF eyebox[8];

		eyebox[0 + 0] = Vector3DF(minx, miny, maxz);
		eyebox[1 + 0] = Vector3DF(maxx, miny, maxz);
		eyebox[2 + 0] = Vector3DF(minx, maxy, maxz);
		eyebox[3 + 0] = Vector3DF(maxx, maxy, maxz);

		eyebox[0 + 4] = Vector3DF(minx, miny, minz);
		eyebox[1 + 4] = Vector3DF(maxx, miny, minz);
		eyebox[2 + 4] = Vector3DF(minx, maxy, minz);
		eyebox[3 + 4] = Vector3DF(maxx, maxy, minz);

		for (int32_t i = 0; i < 8; i++)
		{
			eyebox[i] = cameraProjMatInv.Transform3D(eyebox[i]);
		}

		ofs << viewCullingXDiv << "," << viewCullingYDiv << "," << viewCullingZDiv << std::endl;
		for (int32_t i = 0; i < 8; i++)
		{
			ofs << eyebox[i].X << "," << eyebox[i].Y << "," << eyebox[i].Z << std::endl;
		}
		ofs << std::endl;

		for (int32_t z = 0; z < viewCullingZDiv; z++)
		{
			for (int32_t y = 0; y < viewCullingYDiv; y++)
			{
				for (int32_t x = 0; x < viewCullingXDiv; x++)
				{
					Vector3DF eyebox_[8];

					float xsize = 1.0f / (float) viewCullingXDiv;
					float ysize = 1.0f / (float) viewCullingYDiv;
					float zsize = 1.0f / (float) viewCullingZDiv;

					for (int32_t e = 0; e < 8; e++)
					{
						float x_, y_, z_;
						if (e == 0){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * z; }
						if (e == 1){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * z; }
						if (e == 2){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * z; }
						if (e == 3){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * z; }
						if (e == 4){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * (z + 1); }
						if (e == 5){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * (z + 1); }
						if (e == 6){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * (z + 1); }
						if (e == 7){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * (z + 1); }

						Vector3DF yzMid[4];
						yzMid[0] = eyebox[0] * x_ + eyebox[1] * (1.0f - x_);
						yzMid[1] = eyebox[2] * x_ + eyebox[3] * (1.0f - x_);
						yzMid[2] = eyebox[4] * x_ + eyebox[5] * (1.0f - x_);
						yzMid[3] = eyebox[6] * x_ + eyebox[7] * (1.0f - x_);

						Vector3DF zMid[2];
						zMid[0] = yzMid[0] * y_ + yzMid[1] * (1.0f - y_);
						zMid[1] = yzMid[2] * y_ + yzMid[3] * (1.0f - y_);

						eyebox_[e] = zMid[0] * z_ + zMid[1] * (1.0f - z_);
					}

					Vector3DF max_(-FLT_MAX, -FLT_MAX, -FLT_MAX);
					Vector3DF min_(FLT_MAX, FLT_MAX, FLT_MAX);

					for (int32_t i = 0; i < 8; i++)
					{
						if (eyebox_[i].X > max_.X) max_.X = eyebox_[i].X;
						if (eyebox_[i].Y > max_.Y) max_.Y = eyebox_[i].Y;
						if (eyebox_[i].Z > max_.Z) max_.Z = eyebox_[i].Z;

						if (eyebox_[i].X < min_.X) min_.X = eyebox_[i].X;
						if (eyebox_[i].Y < min_.Y) min_.Y = eyebox_[i].Y;
						if (eyebox_[i].Z < min_.Z) min_.Z = eyebox_[i].Z;
					}

					ofs << x << "," << y << "," << z << std::endl;
					for (int32_t i = 0; i < 8; i++)
					{
						ofs << eyebox_[i].X << "," << eyebox_[i].Y << "," << eyebox_[i].Z << std::endl;
					}
					ofs << max_.X << "," << max_.Y << "," << max_.Z << std::endl;
					ofs << min_.X << "," << min_.Y << "," << min_.Z << std::endl;
					ofs << std::endl;
				}
			}
		}

		ofs << std::endl;
	
		/* レイヤー情報 */
		ofs << layers.size() << std::endl;

		for (size_t i = 0; i < layers.size(); i++)
		{
			auto& layer = layers[i];
			ofs << layer->GetGridXCount() << "," << layer->GetGridYCount() << "," << layer->GetGridZCount() 
				<< "," << layer->GetOffsetX() << "," << layer->GetOffsetY() << "," << layer->GetOffsetZ() << "," << layer->GetGridSize() << std::endl;
		
			for (size_t j = 0; j < layer->GetGrids().size(); j++)
			{
				auto& grid = layer->GetGrids()[j];

				if (grid.GetObjects().size() > 0)
				{
					ofs << j << "," << grid.GetObjects().size() << std::endl;
				}
			}
		}

		Culling(cameraProjMat, isOpenGL);


	}
void mouse_move_func ( int x, int y )
{
	int dx = x - last_x;
	int dy = y - last_y;

	switch ( mode ) {
	case MODE_CAM:
		if ( dragging == DRAG_LEFT ) {
			cam_angs.x += dx;
			cam_angs.y += dy;
			if ( cam_angs.x >= 360.0 )	cam_angs.x -= 360.0;
			if ( cam_angs.x < 0 )		cam_angs.x += 360.0;
			if ( cam_angs.y >= 180.0 )	cam_angs.y = 180.0;
			if ( cam_angs.y <= -180.0 )	cam_angs.y = -180.0;
			printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
			printf ( "Cam To:  %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
			printf ( "Cam FOV: %f\n", cam_fov);
		} else if ( dragging == DRAG_RIGHT ) {
			cam_angs.z += dy*.15;
			if ( cam_angs.z < 0)		cam_angs.z = 0;
			printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
			printf ( "Cam To:  %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
			printf ( "Cam FOV: %f\n", cam_fov );
		}
		break;
	case MODE_CAM_TO:
		if ( dragging == DRAG_LEFT ) {
			cam_to.x += dx;
			cam_to.y += dy;			
		} else if ( dragging == DRAG_RIGHT ) {
			cam_to.z += dy*.05;
			if ( cam_to.z < 0) 	cam_to.z = 0;
		}
		break;	
	case MODE_OBJ:
		if ( dragging == DRAG_LEFT ) {
			obj_angs.x -= dx*0.1;
			obj_angs.y += dy*0.1;
			printf ( "Obj Angs:  %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
			//force_x += dx*.1;
			//force_y += dy*.1;
		} else if (dragging == DRAG_RIGHT) {
			obj_angs.z -= dy*.005;			
			printf ( "Obj Angs:  %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
		}
		psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
		break;
	case MODE_OBJPOS:
		if ( dragging == DRAG_LEFT ) {
			obj_from.x -= dx*.1;
			obj_from.y += dy*.1;
			printf ( "Obj:  %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
		} else if (dragging == DRAG_RIGHT) {
			obj_from.z -= dy*.1;
			printf ( "Obj:  %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
		}
		psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );
		//psys.setPos ( obj_x, obj_y, obj_z, obj_ang, obj_tilt, obj_dist );
		break;
	case MODE_LIGHTPOS:
		if ( dragging == DRAG_LEFT ) {
			light[0].x -= dx*.1;
			light[0].y += dy*.1;		
			printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
		} else if (dragging == DRAG_RIGHT) {
			light[0].z -= dy*.1;			
			printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
		}	
		#ifdef USE_SHADOWS
			setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
		#endif
		break;
	}

	if ( x < 10 || y < 10 || x > 1000 || y > 700 ) {
		glutWarpPointer ( 1024/2, 768/2 );
		last_x = 1024/2;
		last_y = 768/2;
	} else {
		last_x = x;
		last_y = y;
	}
}
void keyboard_func ( unsigned char key, int x, int y )
{
	switch( key ) {
	case 'M': case 'm': {
		psys_nmax *= 2;
		if ( psys_nmax > 65535 ) psys_nmax = 65535;		
		psys.SPH_CreateExample ( psys_demo, psys_nmax );
		} break;
	case 'N': case 'n': {
		psys_nmax /= 2;
		if ( psys_nmax < 64 ) psys_nmax = 64;		
		psys.SPH_CreateExample ( psys_demo, psys_nmax );
		} break;
	case '0':
		UpdateEmit ();
		psys_freq++;	
		psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
		break;  
	case '9':
		UpdateEmit ();
		psys_freq--;  if ( psys_freq < 0 ) psys_freq = 0;
		psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
		break;
	case '.': case '>':
		UpdateEmit ();
		if ( ++psys_rate > 100 ) psys_rate = 100;
		psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
		break;
	case ',': case '<':
		UpdateEmit ();
		if ( --psys_rate < 0 ) psys_rate = 0;
		psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
	break;
	case 'g': case 'G':	psys.Toggle ( USE_CUDA );	break;
	case 'f': case 'F':	mode = MODE_DOF;	break;

	case 'z': case 'Z':	mode = MODE_CAM_TO;	break;
	case 'c': case 'C':	mode = MODE_CAM;	break; 
	case 'h': case 'H':	bHelp = !bHelp; break;
	case 'i': case 'I':	
		UpdateEmit ();
		mode = MODE_OBJPOS;	
		break;
	case 'o': case 'O':	
		UpdateEmit ();
		mode = MODE_OBJ;
		break;  
	case 'x': case 'X':
		if ( ++iClrMode > 2) iClrMode = 0;
		psys.SetParam ( CLR_MODE, iClrMode );
		break;
	case 'l': case 'L':	mode = MODE_LIGHTPOS;	break;
	case 'd': case 'D': {
		int d = psys.GetParam ( PNT_DRAWMODE ) + 1;
		if ( d > 2 ) d = 0;
		psys.SetParam ( PNT_DRAWMODE, d );
		} break;	
	case 's': case 'S':	if ( ++iShade > 2 ) iShade = 0;		break;
	case 27:			    exit( 0 ); break;
	
	case '`':
		bRec = !bRec; break;

	case ' ':		
		//psys.Run (); ptris.Rebuild (); break;
		bPause = !bPause;	break;

	case '\'': case ';':	psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;
	case 'r': case 'R':		psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;  
	case '[':
		psys_demo--;
		if (psys_demo < 0 ) psys_demo = 10;
		psys.SPH_CreateExample ( psys_demo, psys_nmax );
		UpdateEmit ();
		break;
	case ']':
		psys_demo++;
		if (psys_demo > 10 ) psys_demo = 0;
		psys.SPH_CreateExample ( psys_demo, psys_nmax );
		UpdateEmit ();
		break;  
	default:
	break;
  }
}
void FluidSystem::SPH_CreateExample ( int n, int nmax )
{
	Vector3DF pos;
	Vector3DF min, max;
	
	Reset ( nmax );
	
	switch ( n ) {
	case 0:		// Wave pool
				
		//-- TEST CASE: 2x2x2 grid, 32 particles.  NOTE: Set PRADIUS to 0.0004 to reduce wall influence
		//     grid 0:    3*3*2 = 18 particles
		//     grid 1,2:  3*1*2 =  6 particles
		//     grid 3:    1*1*2 =  2 particles
		//     grid 4,5,6:    0 =  0 particles
		/*m_Vec [ SPH_VOLMIN ].Set ( -2.5, -2.5, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 2.5, 2.5, 5.0 );	
		m_Vec [ SPH_INITMIN ].Set ( -2.5, -2.5, 0 );	
		m_Vec [ SPH_INITMAX ].Set ( 2.5, 2.5, 1.6 );*/  
		
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 40 );		

		//m_Vec [ SPH_INITMIN ].Set ( -5, -5, 10 );
		//m_Vec [ SPH_INITMAX ].Set ( 5, 5, 20 );
		
		m_Vec [ SPH_INITMIN ].Set ( -20, -26, 10 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 26, 40 );

		m_Param [ FORCE_XMIN_SIN ] = 12.0;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.05;
		break;
	case 1:		// Dam break
		m_Vec [ SPH_VOLMIN ].Set ( -30, -14, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 14, 60 );
		m_Vec [ SPH_INITMIN ].Set ( 0, -13, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 29, 13, 30 );		
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 2:		// Dual-Wave pool
		m_Vec [ SPH_VOLMIN ].Set ( -60, -5, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 60, 5, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -46, -5, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 46, 5, 15 );
		m_Param [ FORCE_XMIN_SIN ] = 8.0;
		m_Param [ FORCE_XMAX_SIN ] = 8.0;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 3:		// Swirl Stream
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 30, 30, 40 );
		m_Vec [ EMIT_POS ].Set ( -20, -20, 22 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );
		m_Vec [ EMIT_ANG ].Set ( 0, 120, 1.5 );
		m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 4:		// Shockwave
		m_Vec [ SPH_VOLMIN ].Set ( -60, -15, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 60, 15, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -59, -14, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 59, 14, 30 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		m_Toggle [ WALL_BARRIER ] = true;
		m_Toggle [ WRAP_X ] = true;
		break;
	case 5:		// Zero gravity
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
		m_Vec [ EMIT_POS ].Set ( -20, 0, 40 );
		m_Vec [ EMIT_RATE ].Set ( 2, 1, 0 );		
		m_Vec [ EMIT_ANG ].Set ( 0, 120, 0.25 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
		m_Param [ SPH_INTSTIFF ] = 0.20;		
		break;
	case 6:		// Point gravity		
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
		m_Param [ SPH_INTSTIFF ] = 0.50;		
		m_Vec [ EMIT_POS ].Set ( -20, 20, 25 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );		
		m_Vec [ EMIT_ANG ].Set ( -20, 100, 2.0 );
		m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 25 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
		m_Param [ POINT_GRAV ] = 3.5;
		break;
	case 7:		// Levy break
		m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
		m_Vec [ SPH_INITMIN ].Set ( 10, -40, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 40, 40, 50 );
		m_Vec [ EMIT_POS ].Set ( 34, 27, 16.6 );
		m_Vec [ EMIT_RATE ].Set ( 2, 9, 0 );		
		m_Vec [ EMIT_ANG ].Set ( 118, 200, 1.0 );
		m_Toggle [ LEVY_BARRIER ] = true;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.1;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 8:		// Drain
		m_Vec [ SPH_VOLMIN ].Set ( -20, -20, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 20, 20, 50 );
		m_Vec [ SPH_INITMIN ].Set ( -15, -20, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 20, 20, 50 );
		m_Vec [ EMIT_POS ].Set ( -16, -16, 30 );
		m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );		
		m_Vec [ EMIT_ANG ].Set ( -20, 140, 1.8 );
		m_Toggle [ DRAIN_BARRIER ] = true;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	case 9:			// Tumbler
		m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
		m_Vec [ SPH_INITMIN ].Set ( 24, -29, 20 );
		m_Vec [ SPH_INITMAX ].Set ( 29, 29, 40 );
		m_Param [ SPH_VISC ] = 0.1;		
		m_Param [ SPH_INTSTIFF ] = 0.50;
		m_Param [ SPH_EXTSTIFF ] = 8000;
		//m_Param [ SPH_SMOOTHRADIUS ] = 0.01;
		m_Param [ BOUND_ZMIN_SLOPE ] = 0.4;
		m_Param [ FORCE_XMIN_SIN ] = 12.00;
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;	
	case 10:		// Large sim
		m_Vec [ SPH_VOLMIN ].Set ( -35, -35, 0 );
		m_Vec [ SPH_VOLMAX ].Set ( 35, 35, 60 );
		m_Vec [ SPH_INITMIN ].Set ( -5, -35, 0 );
		m_Vec [ SPH_INITMAX ].Set ( 30, 0, 60 );
		m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
		break;
	}	

	SPH_ComputeKernels ();

	m_Param [ SPH_SIMSIZE ] = m_Param [ SPH_SIMSCALE ] * (m_Vec[SPH_VOLMAX].z - m_Vec[SPH_VOLMIN].z);
	m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 );	

	float ss = m_Param [ SPH_PDIST ]*0.87 / m_Param[ SPH_SIMSCALE ];	
	printf ( "Spacing: %f\n", ss);
	AddVolume ( m_Vec[SPH_INITMIN], m_Vec[SPH_INITMAX], ss );	// Create the particles

	float cell_size = m_Param[SPH_SMOOTHRADIUS]*2.0;			// Grid cell size (2r)	
	Grid_Setup ( m_Vec[SPH_VOLMIN], m_Vec[SPH_VOLMAX], m_Param[SPH_SIMSCALE], cell_size, 1.0 );												// Setup grid
	Grid_InsertParticles ();									// Insert particles

	Vector3DF vmin, vmax;
	vmin =  m_Vec[SPH_VOLMIN];
	vmin -= Vector3DF(2,2,2);
	vmax =  m_Vec[SPH_VOLMAX];
	vmax += Vector3DF(2,2,-2);

	#ifdef BUILD_CUDA
		FluidClearCUDA ();
		Sleep ( 500 );

		FluidSetupCUDA ( NumPoints(), sizeof(Fluid), *(float3*)& m_GridMin, *(float3*)& m_GridMax, *(float3*)& m_GridRes, *(float3*)& m_GridSize, (int) m_Vec[EMIT_RATE].x );

		Sleep ( 500 );

		FluidParamCUDA ( m_Param[SPH_SIMSCALE], m_Param[SPH_SMOOTHRADIUS], m_Param[SPH_PMASS], m_Param[SPH_RESTDENSITY], m_Param[SPH_INTSTIFF], m_Param[SPH_VISC] );
	#endif

}
Beispiel #28
0
void Camera3D::draw_gl ()
{
	Vector3DF pnt; 
	int va, vb;
	
	if ( !mOps[0] ) return;

	// Box testing
	//
	// NOTES: This demonstrates AABB box testing against the frustum 
	// Boxes tested are 10x10x10 size, spaced apart from each other so we can see them.
	if ( mOps[5] ) {
		glPushMatrix ();
		glEnable ( GL_LIGHTING );
		glColor3f ( 1, 1, 1 );	
		Vector3DF bmin, bmax, vmin, vmax;
		int lod;
		for (float y=0; y < 100; y += 10.0 ) {
		for (float z=-100; z < 100; z += 10.0 ) {
			for (float x=-100; x < 100; x += 10.0 ) {
				bmin.Set ( x, y, z );
				bmax.Set ( x+8, y+8, z+8 );
				if ( boxInFrustum ( bmin, bmax ) ) {				
					lod = (int) calculateLOD ( bmin, 1, 5, 300.0 );
					//rendGL->drawCube ( bmin, bmax, Vector3DF(1,1,1) );
				}
			}
		}
		}
		glPopMatrix ();
	}

	glDisable ( GL_LIGHTING );	
	glLoadMatrixf ( getViewMatrix().GetDataF() );

	// Frustum planes (world space)
	//
	// NOTE: The frustum planes are drawn as discs because
	// they are boundless (infinite). The minimum information contained in the
	// plane equation is normal direction and distance from plane to origin.
	// This sufficiently defines infinite planes for inside/outside testing,
	// but cannot be used to draw the view frustum without more information.
	// Drawing is done as discs here to verify the frustum plane equations.
	if ( mOps[2] ) {
		glBegin ( GL_POINTS );
		glColor3f ( 1, 1, 0 );
		Vector3DF norm;
		Vector3DF side, up;
		for (int n=0; n < 6; n++ ) {
			norm.Set ( frustum[n][0], frustum[n][1], frustum[n][2] );
			glColor3f ( n/6.0, 1.0- (n/6.0), 0.5 );
			side = Vector3DF(0,1,0); side.Cross ( norm ); side.Normalize ();	
			up = side; up.Cross ( norm ); up.Normalize();
			norm *= frustum[n][3];
			for (float y=-50; y < 50; y += 1.0 ) {
				for (float x=-50; x < 50; x += 1.0 ) {
					if ( x*x+y*y < 1000 ) {
						//pnt = side * x + up * y - norm; 
                        pnt = side;
                        Vector3DF tv = up;

                        tv *= y;
                        pnt *= x;
                        pnt += tv;
                        pnt -= norm;

						glVertex3f ( pnt.x, pnt.y, pnt.z );
					}
				}
			}
		}
		glEnd (); 
	}

	// Inside/outside testing
	//
	// NOTES: This code demonstrates frustum clipping 
	// tests on individual points.
	if ( mOps[4] ) {
		glColor3f ( 1, 1, 1 );
		glBegin ( GL_POINTS );
		for (float z=-100; z < 100; z += 4.0 ) {
			for (float y=0; y < 100; y += 4.0 ) {
				for (float x=-100; x < 100; x += 4.0 ) {
					if ( pointInFrustum ( x, y, z) ) {
						glVertex3f ( x, y, z );
					}
				}
			}
		}
		glEnd ();
	}
	
	// Inverse rays (world space)
	//
	// NOTES: This code demonstrates drawing 
	// inverse camera rays, as might be needed for raytracing or hit testing.
	if ( mOps[3] ) {
		glBegin ( GL_LINES );
		glColor3f ( 0, 1, 0);
		for (float x = 0; x <= 1.0; x+= 0.5 ) {
			for (float y = 0; y <= 1.0; y+= 0.5 ) {
				pnt = inverseRay ( x, y, mFar );
				pnt += from_pos;
				glVertex3f ( from_pos.x, from_pos.y, from_pos.z );		// all inverse rays originate at the camera center
				glVertex3f ( pnt.x, pnt.y, pnt.z );
			}
		}
		glEnd ();
	}

	// Projection
	//
	// NOTES: This code demonstrates 
	// perspective projection _without_ using the OpenGL pipeline.
	// Projection is done by the camera class. A cube is drawn on the near plane.
	
	// Cube geometry
	Vector3DF pnts[8];
	Vector3DI edge[12];
	pnts[0].Set (  0,  0,  0 );	pnts[1].Set ( 10,  0,  0 ); pnts[2].Set ( 10,  0, 10 ); pnts[3].Set (  0,  0, 10 );		// lower points (y=0)
	pnts[4].Set (  0, 10,  0 );	pnts[5].Set ( 10, 10,  0 ); pnts[6].Set ( 10, 10, 10 ); pnts[7].Set (  0, 10, 10 );		// upper points (y=10)
	edge[0].Set ( 0, 1, 0 ); edge[1].Set ( 1, 2, 0 ); edge[2].Set ( 2, 3, 0 ); edge[3].Set ( 3, 0, 0 );					// 4 lower edges
	edge[4].Set ( 4, 5, 0 ); edge[5].Set ( 5, 6, 0 ); edge[6].Set ( 6, 7, 0 ); edge[7].Set ( 7, 4, 0 );					// 4 upper edges
	edge[8].Set ( 0, 4, 0 ); edge[9].Set ( 1, 5, 0 ); edge[10].Set ( 2, 6, 0 ); edge[11].Set ( 3, 7, 0 );				// 4 vertical edges
	
	// -- White cube is drawn using OpenGL projection
	if ( mOps[6] ) {
		glBegin ( GL_LINES );
		glColor3f ( 1, 1, 1);
		for (int e = 0; e < 12; e++ ) {
			va = edge[e].x;
			vb = edge[e].y;
			glVertex3f ( pnts[va].x, pnts[va].y, pnts[va].z );
			glVertex3f ( pnts[vb].x, pnts[vb].y, pnts[vb].z );
		}
		glEnd ();	
	}

	//---- Draw the following in camera space..
	// NOTES:
	// The remainder drawing steps are done in 
	// camera space. This is done by multiplying by the
	// inverse_rotation matrix, which transforms from camera to world space.
	// The camera axes, near, and far planes can now be drawn in camera space.
	glPushMatrix ();
	glLoadMatrixf ( getViewMatrix().GetDataF() );
	glTranslatef ( from_pos.x, from_pos.y, from_pos.z );
	glMultMatrixf ( invrot_matrix.GetDataF() );				// camera space --to--> world space

	// -- Red cube is drawn on the near plane using software projection pipeline. See Camera3D::project
	if ( mOps[6] ) {
		glBegin ( GL_LINES );
		glColor3f ( 1, 0, 0);
		Vector4DF proja, projb;
		for (int e = 0; e < 12; e++ ) {
			va = edge[e].x;
			vb = edge[e].y;
			proja = project ( pnts[va] );
			projb = project ( pnts[vb] );
			if ( proja.w > 0 && projb.w > 0 && proja.w < 1 && projb.w < 1) {	// Very simple Z clipping  (try commenting this out and see what happens)
				glVertex3f ( proja.x, proja.y, proja.z );
				glVertex3f ( projb.x, projb.y, projb.z );
			}
		}
		glEnd ();
	}
	// Camera axes
	glBegin ( GL_LINES );
	float to_d = (from_pos - to_pos).Length();
	glColor3f ( .8,.8,.8); glVertex3f ( 0, 0, 0 );	glVertex3f ( 0, 0, -to_d );
	glColor3f ( 1,0,0); glVertex3f ( 0, 0, 0 );		glVertex3f ( 10, 0, 0 );
	glColor3f ( 0,1,0); glVertex3f ( 0, 0, 0 );		glVertex3f ( 0, 10, 0 );
	glColor3f ( 0,0,1); glVertex3f ( 0, 0, 0 );		glVertex3f ( 0, 0, 10 );
	glEnd ();

	if ( mOps[1] ) {
		// Near plane
		float sy = tan ( mFov * DEGtoRAD / 2.0);
		float sx = sy * mAspect;
		glColor3f ( 0.8, 0.8, 0.8 );
		glBegin ( GL_LINE_LOOP );
		glVertex3f ( -mNear*sx,  mNear*sy, -mNear );
		glVertex3f (  mNear*sx,  mNear*sy, -mNear );
		glVertex3f (  mNear*sx, -mNear*sy, -mNear );
		glVertex3f ( -mNear*sx, -mNear*sy, -mNear );
		glEnd ();
		// Far plane
		glBegin ( GL_LINE_LOOP );
		glVertex3f ( -mFar*sx,  mFar*sy, -mFar );
		glVertex3f (  mFar*sx,  mFar*sy, -mFar );
		glVertex3f (  mFar*sx, -mFar*sy, -mFar );
		glVertex3f ( -mFar*sx, -mFar*sy, -mFar );
		glEnd ();

		// Subview Near plane
		float l, r, t, b;
		l = -sx + 2.0*sx*mTile.x;						// Tile is in range 0 <= x,y <= 1
		r = -sx + 2.0*sx*mTile.z;
		t =  sy - 2.0*sy*mTile.y;
		b =  sy - 2.0*sy*mTile.w;
		glColor3f ( 0.8, 0.8, 0.0 );
		glBegin ( GL_LINE_LOOP );
		glVertex3f ( l * mNear, t * mNear, -mNear );
		glVertex3f ( r * mNear, t * mNear, -mNear );
		glVertex3f ( r * mNear, b * mNear, -mNear );
		glVertex3f ( l * mNear, b * mNear, -mNear );		
		glEnd ();
		// Subview Far plane
		glBegin ( GL_LINE_LOOP );
		glVertex3f ( l * mFar, t * mFar, -mFar );
		glVertex3f ( r * mFar, t * mFar, -mFar );
		glVertex3f ( r * mFar, b * mFar, -mFar );
		glVertex3f ( l * mFar, b * mFar, -mFar );		
		glEnd ();
	}

	glPopMatrix ();
}