⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chcollision.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
} 

#if 1
#define WIDTH 4
#define HEIGHT 4

//unsigned char buffer1[WIDTH * HEIGHT * 4];

#if (defined(CH_USE_RLAB))
static RLImage stockImage = {
	WIDTH, HEIGHT,	/* width, height	*/
	2, 1,			/* aspectx, aspecty */
	24,			/* depth 	*/
	TRUE,			/* rgb 	*/
	WIDTH*4,		/* bytes_per_line */
	0,		/* buffer1 	*/
	NULL,			/* buffer2 	*/
	0xff0000,		/* red mask 	*/
     0xff00,		/* green mask 	*/
	0xff,			/* blue mask 	*/
	0,			/* alpha mask 	*/
	0,			/* palette size 	*/
	NULL,			/* palette 	*/
};

#define ZBUFFERDEPTH	16
#endif

ChCollisionView::ChCollisionView(ChRenderContext *pRC, ChNrViewport sceneView, ChNrFrame scene, ChNrFrame sceneCamera ) :
	m_buffer(0), m_zBuffer(0)
	#if (defined(CH_USE_D3D))
	, m_pDevice(0)
	#endif
{
    m_camera = pRC->CreateFrame(sceneCamera);
    ChNrFrameSetPosition(m_camera, sceneCamera, 0, 0, 0);
    ChNrFrameSetOrientation(m_camera, sceneCamera,
				   0, 0, -1,
				   0, 1, 0);  // point backwards to start

#if (defined(CH_USE_RLAB))
						  // Set up the image buffer
	m_image = stockImage;
	
	m_buffer = new unsigned char [WIDTH * HEIGHT * 4];
	::memset(m_buffer, 0,  WIDTH * HEIGHT * 4);

	m_image.buffer1 = m_buffer;
						 // Now set up the z buffer
	m_zBufferImage = stockImage;
	m_zBufferImage.depth = ZBUFFERDEPTH;
	m_zBufferImage.bytes_per_line = ZBUFFERDEPTH / 8 * m_zBufferImage.width;

	m_zBuffer = new unsigned char [WIDTH * HEIGHT * ZBUFFERDEPTH / 8];
	::memset(m_zBuffer, 0,  WIDTH * HEIGHT * ZBUFFERDEPTH / 8);
	m_zBufferImage.buffer1 = m_zBuffer;



    m_dev = RLCreateMemoryDevice(&m_image, /*0*/ &m_zBufferImage  , NULL, NULL, NULL, NULL);
#elif (defined(CH_USE_D3D))
	m_pDevice = new ChDevice3D(pRC, WIDTH, HEIGHT);
	m_dev = m_pDevice->GetDevice();
#endif

    ChNrDeviceSetQuality(m_dev, RenderFlat);
    m_view = pRC->CreateViewport(m_dev, m_camera, 0, 0,
				     ChNrDeviceGetWidth(m_dev),
				     ChNrDeviceGetHeight(m_dev));
	m_scene = scene;
	m_sceneCamera = sceneCamera;

	ChNrViewportSetProjection(m_view, ChNrViewportGetProjection(sceneView) );
	ChNrViewportSetFront(m_view, ChNrViewportGetFront(sceneView) /  NEAR_PLANE_SCALE);	// as close as possible
	ChNrViewportSetBack(m_view, ChNrViewportGetBack(sceneView));

#ifdef _DEBUG
	float front = ChNrViewportGetFront(sceneView);
	float back =  ChNrViewportGetBack(sceneView);
	//int field = int(ChNrViewportGetField(sceneView) * 4. / ChNrViewportGetHeight(sceneView));
#endif

	float field = (ChNrViewportGetField(sceneView) * 4. / ChNrViewportGetHeight(sceneView));
	ChNrViewportSetField(m_view, field / NEAR_PLANE_SCALE);

    //RLTick(); /* render a scene */


}
ChCollisionView::~ChCollisionView()
{
    if(m_view) ChNrObjectDestroy(m_view);
	m_view = 0;

#if (defined(CH_USE_RLAB))
    if(m_dev) ChNrObjectDestroy(m_dev);
	m_dev = 0;
#elif (defined(CH_USE_D3D))
// delete the rcdevice
	delete m_pDevice;
#endif
	delete [] m_buffer;
	m_buffer = 0;
	delete [] m_zBuffer;
	m_zBuffer = 0;
	
}

void ChCollisionView::SetDir(GxVec3f dir)
{
	dir.normalize();
	//dir .z() = -dir.z();
	dir .x() = -dir.x();
	dir .y() = -dir.y();

	GxVec3f xAxis(1, 0, 0), yAxis(0, 1, 0), sideways, up;

	if(dir.dot(yAxis) > .9)
	{
		sideways = dir.cross(xAxis);
	}
	else
	{
		sideways = dir.cross(yAxis);
	}
	up = sideways.cross(dir);


    ChNrFrameSetOrientation(m_camera, m_scene,
				   dir.x(), dir.y(), dir.z(),
				   up.x(), up.y(), up.z());
	SetBack();  

};
void ChCollisionView::SetRelativeDir(GxVec3f dir)
{
	dir.normalize();

	GxVec3f xAxis(1, 0, 0), yAxis(0, 1, 0), sideways, up;

	if(dir.dot(yAxis) > .9)
	{
		sideways = dir.cross(xAxis);
	}
	else
	{
		sideways = dir.cross(yAxis);
	}
	up = sideways.cross(dir);

    ChNrFrameSetOrientation(m_camera, m_sceneCamera,
				   dir.x(), dir.y(), dir.z(),
				   up.x(), up.y(), up.z());  
	SetBack();  

}
void ChCollisionView::SetBack()
{
			  // Step back a bit for the collision view from the current camera loc
			  // to account for the near clipping plane
	GxVec3f dir, up;


    ChNrFrameGetOrientation(m_camera, m_sceneCamera,
				   (ChNrVector*)&dir,
				   (ChNrVector*)&up);  
	dir.normalize();

	dir *= -ChNrViewportGetFront(m_view);
    ChNrFrameSetPosition(m_camera, m_sceneCamera,
				   dir.x(), dir.y(), dir.z());  
}

void ChCollisionView::Render()
{
#if (defined(CH_USE_RLAB))
	::memset(m_zBuffer, 0xff,  WIDTH * HEIGHT * ZBUFFERDEPTH / 8);
#endif
	ChNrViewportClear(m_view);
	ChNrViewportRender(m_view, m_scene);
	ChNrDeviceUpdate(m_dev);

}

float ChCollisionView::GetZ()
{
#if (defined(CH_USE_RLAB))
	GxVec3f pt;
	ChNrVector4d screenCoord;
	unsigned short	zMin = 0xffff;
	int width = ChNrViewportGetWidth(m_view);
	int height = ChNrViewportGetHeight(m_view);
	for(int x = 0; x < width; x++)
	{
		for(int y = 0; y < height; y++)
		{
			int index = y * m_zBufferImage.bytes_per_line / 2 + x ;
			unsigned short	z = ((unsigned short*)m_zBufferImage.buffer1)[index];
			zMin = min(z, zMin);
		}
	}

	if(zMin == 0xffff) return CH_INFINITE_RANGE; // free to move if nothing drawn

	screenCoord.x = 0;
	screenCoord.y = 0;
	#if 1
	screenCoord.x = width / 2;
	screenCoord.y = height / 2;
	#endif
	screenCoord.z =  float(zMin) / 65535.;
	screenCoord.w = 1;
	ChNrViewportInverseTransform(m_view, (ChNrVector*)&pt, &screenCoord);

	// Convert to camera coords
	GxVec3f ptInCameraSpace;
	ChNrFrameInverseTransform(m_camera, (ChNrVector*)&ptInCameraSpace, (ChNrVector*)&pt);

	return ptInCameraSpace.z();
#else
	return 0;
#endif
}


#endif	// 0 or 1

#if (defined(CH_USE_D3D))

// Just stubs to get us going on d3d
#pragma message("D3D Collision Testing Not done!")

#if 0
float ChRenderContext::GetCollisionRange(GxVec3f &look, bool boolRelative /* = false*/)
{
	// Return the range the current camera can be moved without colliding with something
	// value is in -camera- coords

	float range = CH_INFINITE_RANGE; // free to move if no scene
	return range;
};
#endif


#elif (defined(CH_USE_RLAB))


//#define BE_VERY_NOISY_ON_COLLISION_TESTING 1
float ChRenderContext::GetAvatarRadius()
{
	return .1;	// bout the size of your head
};

float ChRenderContext::GetCollisionRange()
{
	// Return the range the current camera can be moved without colliding with something
	// value is in -camera- coords

	float range = CH_INFINITE_RANGE; // free to move if no scene

	if(m_viewport)
	{
		ChNrFrame frame;

		// Lock the scene and don't be nice
		LockScene();
	
		int iX = ChNrViewportGetWidth(m_viewport) / 2;
		int iY = ChNrViewportGetHeight(m_viewport) / 2;
		RLVisual visual;

		if(ChNrViewportFindVisual( m_viewport, &visual, &frame, iX, iY) != RLNotFound)
		{
			// Hit -something-. How far away is it?
			GxVec3f clickPoint;
			ChNrFaceInfo faceInfo;
			if((ChNrViewportFindFace( m_viewport, &faceInfo, iX, iY) != RLNotFound)
						&& faceInfo.frame == frame)
			{
				clickPoint = *(GxVec3f*)&faceInfo.position;
				ChNrVector4d screenCoord;
				screenCoord.x = clickPoint.x();
				screenCoord.y = clickPoint.y();
				screenCoord.z = clickPoint.z();
				screenCoord.w = 1;
				ChNrViewportInverseTransform(m_viewport, (ChNrVector*)&clickPoint, &screenCoord);
			}
			else
			{
				// It's not a face visual, must be a decal
				ChNrFrameGetPosition(frame, m_sceneFrame, (ChNrVector*)&clickPoint);
			}

			// Convert to camera coords
			GxVec3f ptInCameraSpace;
			ChNrFrameInverseTransform(m_cameraFrame, (ChNrVector*)&ptInCameraSpace, (ChNrVector*)&clickPoint);
			
			// take range - I'm not sure if this works if we have a scaling transform before the camera
			range = ptInCameraSpace.magnitude() - 	ChNrViewportGetFront(m_viewport);
			range = max(range, 0.); 

		}

		UnlockScene();

	}
	
	return range;

} 

#endif

// end of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -