Пример #1
0
/**
 * Renders a scene not to the screen but into a texture
 */
void drawSceneToSpecificFramebuffer(GLuint fbo, int renderToTexture) {
    /**
     * Drawing into the given framebuffer-object
     */
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    if (renderToTexture) {
        glClearColor(0.0, 0.8, 0.8, 0.0);
    } else {
        glClearColor(0.0, 1.0, 1.0, 0.0);
    }
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDisable(GL_CULL_FACE);
    glViewport (0, 0, G_Width, G_Height);
    setProjection ((double)G_Width/G_Height);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (getCameraPosition(0), getCameraPosition(1), getCameraPosition(2),
         0.0, 0.0, 0.0,
         0.0, 1.0, 0.0);

    glDisable(GL_TEXTURE_2D);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        printf ("Framebuffer is not correct!\n");
    }

    drawDemo(renderToTexture);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Пример #2
0
void drawAtmosphere()
{
	glUseProgram(atmosphereShader);
	setupLighting(atmosphereShader);
	vec3 Position = getCameraPosition();
	v = getViewMatrix();
	
	for(int i = 0; i < 11; i++)
    {	
    	float scaleFactor = 1.025;
    	m = multiplymat4(planetInstanceArray[i].planetLocation, scale(scaleFactor));
    	
    	float fOuter = planetInstanceArray[i].size*100*scaleFactor;
		float fInner = (planetInstanceArray[i].size*100);
		
		//float fOuter = (fScale);
		//float fInner = fScale/scaleFactor;
		
		//printf("fInner: %f, fOuter: %f\n", fInner, 1/(fOuter-fInner));
		//printf("camera: %f, %f, %f\n", Position.x, Position.y, Position.z);
		//printf("camera: %f, %f, %f\n", 1.0f / pow(0.650f, 4.0f), 1.0f / pow(0.570f, 4.0f), 1.0f / pow(0.475f, 4.0f));
		
		glUniform4f(glGetUniformLocation(atmosphereShader, "LightPosition"), light_position.x, light_position.y, light_position.z, light_position.w);
    	glUniform3f(glGetUniformLocation(atmosphereShader, "camPosition"), Position.x, Position.y, Position.z);
    	glUniform3f(glGetUniformLocation(atmosphereShader, "v3InvWavelength"), 1.0f / pow(0.650f, 4.0f), 1.0f / pow(0.570f, 4.0f), 1.0f / pow(0.475f, 4.0f));
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fCameraHeight"), lengthvec3(getCameraPosition()));
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fCameraHeight2"), (lengthvec3(getCameraPosition())) * (lengthvec3(getCameraPosition())));
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fInnerRadius"), fInner);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fInnerRadius2"), fInner*fInner);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fOuterRadius"), fOuter);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fOuterRadius2"), fOuter*fOuter);
    
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fKrESun"), 0.0025f * 20.0f);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fKmESun"), 0.0015f * 20.0f);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fKr4PI"), 0.0025f * 4.0f * 3.141592653f);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fKm4PI"), 0.0015f * 4.0f * 3.141592653f);
    
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fScale"), 1/(fOuter-fInner));
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fScaleDepth"), 0.25);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "fScaleOverScaleDepth"), 1.0/(fOuter-fInner)/0.25);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "g"), -0.990f);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "g2"), -0.990f*-0.990f);
    	glUniform1f(glGetUniformLocation(atmosphereShader, "time"), glfwGetTime());
    	
    	initMVP(atmosphereShader, m, v);
    	
    	glBindVertexArray (atmosphereVAO);
    	glDrawArrays( GL_TRIANGLES, 0, planet.vertexNumber);
    	glBindVertexArray(0);
    }
}
void	DemoApplication::shootBox(const btVector3& destination)
{

	if (m_dynamicsWorld)
	{
		float mass = 1.f;
		btTransform startTransform;
		startTransform.setIdentity();
		btVector3 camPos = getCameraPosition();
		startTransform.setOrigin(camPos);

		setShootBoxShape ();

		btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape);
		body->setLinearFactor(btVector3(1,1,1));
		//body->setRestitution(1);

		btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
		linVel.normalize();
		linVel*=m_ShootBoxInitialSpeed;

		body->getWorldTransform().setOrigin(camPos);
		body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
		body->setLinearVelocity(linVel);
		body->setAngularVelocity(btVector3(0,0,0));
		body->setCcdMotionThreshold(1.);
		body->setCcdSweptSphereRadius(0.2f);
		
	}
}
Пример #4
0
bool VoxelNodeData::updateCurrentViewFrustum() {
    bool currentViewFrustumChanged = false;
    ViewFrustum newestViewFrustum;
    // get position and orientation details from the camera
    newestViewFrustum.setPosition(getCameraPosition());
    newestViewFrustum.setOrientation(getCameraOrientation());

    // Also make sure it's got the correct lens details from the camera
    float originalFOV = getCameraFov();
    float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
    
    newestViewFrustum.setFieldOfView(wideFOV); // hack
    newestViewFrustum.setAspectRatio(getCameraAspectRatio());
    newestViewFrustum.setNearClip(getCameraNearClip());
    newestViewFrustum.setFarClip(getCameraFarClip());
    newestViewFrustum.setEyeOffsetPosition(getCameraEyeOffsetPosition());
    
    // if there has been a change, then recalculate
    if (!newestViewFrustum.matches(_currentViewFrustum)) {
        _currentViewFrustum = newestViewFrustum;
        _currentViewFrustum.calculate();
        currentViewFrustumChanged = true;
    }
    
    // When we first detect that the view stopped changing, we record this.
    // but we don't change it back to false until we've completely sent this
    // scene.
    if (_viewFrustumChanging && !currentViewFrustumChanged) {
        _viewFrustumJustStoppedChanging = true;
    }
    _viewFrustumChanging = currentViewFrustumChanged;
    return currentViewFrustumChanged;
}
Пример #5
0
Position MapView::getPosition(const Point& point, const Size& mapSize)
{
    Position cameraPosition = getCameraPosition();

    // if we have no camera, its impossible to get the tile
    if(!cameraPosition.isValid())
        return Position();

    Rect srcRect = calcFramebufferSource(mapSize);
    float sh = srcRect.width() / (float)mapSize.width();
    float sv = srcRect.height() / (float)mapSize.height();

    Point framebufferPos = Point(point.x * sh, point.y * sv);
    Point centerOffset = (framebufferPos + srcRect.topLeft()) / m_tileSize;

    Point tilePos2D = getVisibleCenterOffset() - m_drawDimension.toPoint() + centerOffset + Point(2,2);
    if(tilePos2D.x + cameraPosition.x < 0 && tilePos2D.y + cameraPosition.y < 0)
        return Position();

    Position position = Position(tilePos2D.x, tilePos2D.y, 0) + cameraPosition;

    if(!position.isValid())
        return Position();

    return position;
}
void	DemoApplication::shootBox(const btVector3& destination)
{

	if (m_dynamicsWorld)
	{
		float mass = 1.f*1000.;
		btTransform startTransform;
		startTransform.setIdentity();
		btVector3 camPos = getCameraPosition();
		startTransform.setOrigin(camPos);

		setShootBoxShape ();

		btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape,3,1|2);
		body->setUserPointer((void*)-1);
		
		body->setLinearFactor(btVector3(1,1,1));
		//body->setRestitution(1);

		btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
		linVel.normalize();
		linVel*=m_ShootBoxInitialSpeed;

		body->getWorldTransform().setOrigin(camPos);
		body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
		body->setLinearVelocity(linVel);
		body->setAngularVelocity(btVector3(0,0,0));
		body->setCcdMotionThreshold(0.5);
		body->setCcdSweptSphereRadius(0.4f);//value should be smaller (embedded) than the half extends of the box (see ::setShootBoxShape)
//		printf("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid());
//		printf("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ());
//		printf("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ());
		
	}
}
Пример #7
0
//------------------------------------------------------------------------------
void GimpactConcaveDemo::shootTrimesh(const btVector3& destination)
{

	if (m_dynamicsWorld)
	{
		float mass = 4.f;
		btTransform startTransform;
		startTransform.setIdentity();
		btVector3 camPos = getCameraPosition();
		startTransform.setOrigin(camPos);
#ifdef BULLET_GIMPACT
		btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_trimeshShape2);
#else
		btRigidBody* body = this->localCreateRigidBody(mass, startTransform,createBunnyShape());
#endif
		btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
		linVel.normalize();
		linVel*=m_ShootBoxInitialSpeed*0.25;

		body->getWorldTransform().setOrigin(camPos);
		body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
		body->setLinearVelocity(linVel);
		body->setAngularVelocity(btVector3(0,0,0));
	}
}
Пример #8
0
void shootBox(const btVector3& destination)
{
	float mass = 1.f;
	btTransform startTransform;
	startTransform.setIdentity();
	btVector3 camPos = getCameraPosition();
	startTransform.setOrigin(camPos);



	const btScalar BOX_DIMENSIONS = 3.0f;

	btBoxShape* box = new btBoxShape( btVector3(BOX_DIMENSIONS, 0.1f, BOX_DIMENSIONS*4/3) );
	box->initializePolyhedralFeatures();
	m_shootBoxShape = box;

	btRigidBody* body = localCreateRigidBody(mass, startTransform,m_shootBoxShape);
	body->setLinearFactor(btVector3(1,1,1));
	//body->setRestitution(1);

	btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
	linVel.normalize();
	linVel*=m_ShootBoxInitialSpeed;

	body->getWorldTransform().setOrigin(camPos);
	body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
	body->setLinearVelocity(linVel);
	body->setAngularVelocity(btVector3(0,0,0));
	body->setCcdMotionThreshold(0.5);
	body->setCcdSweptSphereRadius(0.4f);//value should be smaller (embedded) than the half extends of the box (see ::setShootBoxShape)
	LOGI("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid());
	LOGI("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ());
	LOGI("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ());

}
Пример #9
0
void drawPlanet()
{   
	glUseProgram(planetShader);
	setupLighting(planetShader);
	vec3 Position = getCameraPosition();
	v = getViewMatrix();
		
	for(int i = 0; i < 11; i++)
	{	
		mat4 rotation = multiplymat4(rotateY(rotationSpeedArray[i]), rotateX(planetInstanceArray[i].axialTilt+45));
		mat4 translation = multiplymat4(translate(planetInstanceArray[i].radius*1000, 0.0, 0.0), rotation);
		mat4 b = translate(0.0, 0.0, -400.0);
		mat4 roty = rotateY(orbitSpeedArray[i]);
		mat4 rotxy = multiplymat4(b, roty);
		mat4 c = multiplymat4(rotxy, translation);
		m = multiplymat4(c, scale(planetInstanceArray[i].size*100));
		planetInstanceArray[i].planetLocation = m;
    	
		//mv = modelMatrices[i];
		initMVP(planetShader, m, v);
		glUniform3f(glGetUniformLocation(planetShader, "cameraPos"), Position.x, Position.y, Position.z);
    
    	glBindVertexArray (planetVAO);
    	bindTexture(GL_TEXTURE0, planetInstanceArray[i].texture);
    	bindTexture(GL_TEXTURE1, planetInstanceArray[i].normal);
    	glUniform1i(glGetUniformLocation(planetShader, "tex"), 0);
    	glUniform1i(glGetUniformLocation(planetShader, "normalTex"), 1);
    	glDrawArrays( GL_TRIANGLES, 0, planet.vertexNumber);
    	glBindVertexArray(0);
    }
}
Пример #10
0
void drawSun()
{   
	glUseProgram(sunShader);
	
	setupLighting(sunShader);
	
	//glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO);
	vec3 Position = getCameraPosition();
	
	v = getViewMatrix();
	
	mat4 a = translate(0.0, 0.0, -400.0); //333.0 Times
	mat4 rotation = rotateY(thetaY);
	mat4 b = multiplymat4(a, rotation);
	m = multiplymat4(b, scale(100.0));
	
	initMVP(sunShader, m, v);
	glUniform3f(glGetUniformLocation(sunShader, "cameraPos"), Position.x, Position.y, Position.z);
	glUniform1f(glGetUniformLocation(sunShader, "systemTime"), glfwGetTime());
    
    glBindVertexArray (planetVAO);
    bindTexture(GL_TEXTURE0, sunTexture);
    bindTexture(GL_TEXTURE1, sunNormal);
    glUniform1i(glGetUniformLocation(sunShader, "tex"), 0);
    glUniform1i(glGetUniformLocation(sunShader, "normalTex"), 1);
    
    glDrawArrays( GL_TRIANGLES, 0, planet.vertexNumber );
    glBindVertexArray(0);
    //glBindFramebuffer(GL_FRAMEBUFFER, 0);  
    
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, colorBuffer);
    glUniform1f(glGetUniformLocation(sunShader, "exposure"), 1.0);
}
Пример #11
0
void OsgSceneWindow::Frame() {
	osg::ref_ptr<osgGA::TrackballManipulator> manipulator = getTrackballManipulator();
	osg::Vec3 cameraTarget = manipulator->getCenter();
	m_Scene->updateDynamicGrid(cameraTarget, getCameraPosition());

	OsgGraphicsWindow::Frame();
}
Пример #12
0
/**
 * Main Programme
 */
int main(int argc, char** argv)
{
  
    glutInit(&argc, argv);

    //framebuffer setup
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );

    // positioning and size of window
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(WindowSize_X,WindowSize_Y);
    glutCreateWindow(argv[0]);	

    //initialize viewpoint
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0,0,-4);
    tbInitTransform();     // This is for the trackball, please ignore
    tbHelp();             // idem
	MyCameraPosition=getCameraPosition();

	//activate the light following the camera
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    glEnable(GL_COLOR_MATERIAL);
    int LightPos[4] = {0,0,2,0};
    int MatSpec [4] = {1,1,1,1};
    glLightiv(GL_LIGHT0,GL_POSITION,LightPos);

	//normals will be normalized in the graphics pipeline
	glEnable(GL_NORMALIZE);
    //clear color of the background is black.
	glClearColor (0.0, 0.0, 0.0, 0.0);

	// Activate rendering modes
    //activate depth test
	glEnable( GL_DEPTH_TEST ); 
    //draw front-facing triangles filled
	//and back-facing triangles as wires
    glPolygonMode(GL_FRONT,GL_FILL);
    glPolygonMode(GL_BACK,GL_LINE);
    //interpolate vertex colors over the triangles
	glShadeModel(GL_SMOOTH);

	// glut setup... to ignore
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutDisplayFunc(display);
    glutMouseFunc(tbMouseFunc);    // trackball
    glutMotionFunc(tbMotionFunc);  // uses mouse
    glutIdleFunc( animate);

	init();

	//main loop for glut... this just runs your application
    glutMainLoop();
        
    return 0;  // execution never reaches this point
}
Пример #13
0
int MapView::calcFirstVisibleFloor()
{
    int z = 7;
    // return forced first visible floor
    if(m_lockedFirstVisibleFloor != -1) {
        z = m_lockedFirstVisibleFloor;
    } else {
        Position cameraPosition = getCameraPosition();

        // this could happens if the player is not known yet
        if(cameraPosition.isValid()) {
            // avoid rendering multifloors in far views
            if(!m_multifloor) {
                z = cameraPosition.z;
            } else {
                // if nothing is limiting the view, the first visible floor is 0
                int firstFloor = 0;

                // limits to underground floors while under sea level
                if(cameraPosition.z > Otc::SEA_FLOOR)
                    firstFloor = std::max(cameraPosition.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::UNDERGROUND_FLOOR);

                // loop in 3x3 tiles around the camera
                for(int ix = -1; ix <= 1 && firstFloor < cameraPosition.z; ++ix) {
                    for(int iy = -1; iy <= 1 && firstFloor < cameraPosition.z; ++iy) {
                        Position pos = cameraPosition.translated(ix, iy);

                        // process tiles that we can look through, e.g. windows, doors
                        if((ix == 0 && iy == 0) || (/*(std::abs(ix) != std::abs(iy)) && */g_map.isLookPossible(pos))) {
                            Position upperPos = pos;
                            Position coveredPos = pos;

                            while(coveredPos.coveredUp() && upperPos.up() && upperPos.z >= firstFloor) {
                                // check tiles physically above
                                TilePtr tile = g_map.getTile(upperPos);
                                if(tile && tile->limitsFloorsView()) {
                                    firstFloor = upperPos.z + 1;
                                    break;
                                }

                                // check tiles geometrically above
                                tile = g_map.getTile(coveredPos);
                                if(tile && tile->limitsFloorsView()) {
                                    firstFloor = coveredPos.z + 1;
                                    break;
                                }
                            }
                        }
                    }
                }
                z = firstFloor;
            }
        }
    }

    // just ensure the that the floor is in the valid range
    z = std::min(std::max(z, 0), (int)Otc::MAX_Z);
    return z;
}
Пример #14
0
bool UIMinimap::floorDown()
{
    Position pos = getCameraPosition();
    if(!pos.down())
        return false;
    setCameraPosition(pos);
    return true;
}
Пример #15
0
void UIMinimap::drawSelf(Fw::DrawPane drawPane)
{
    UIWidget::drawSelf(drawPane);

    if((drawPane & Fw::ForegroundPane) == 0)
        return;

    g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale, m_color);
}
Пример #16
0
bool OctreeQueryNode::updateCurrentViewFrustum() {
    // if shutting down, return immediately
    if (_isShuttingDown) {
        return false;
    }

    bool currentViewFrustumChanged = false;
    ViewFrustum newestViewFrustum;
    // get position and orientation details from the camera
    newestViewFrustum.setPosition(getCameraPosition());
    newestViewFrustum.setOrientation(getCameraOrientation());

    // Also make sure it's got the correct lens details from the camera
    float originalFOV = getCameraFov();
    float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;

    newestViewFrustum.setFieldOfView(wideFOV); // hack
    newestViewFrustum.setAspectRatio(getCameraAspectRatio());
    newestViewFrustum.setNearClip(getCameraNearClip());
    newestViewFrustum.setFarClip(getCameraFarClip());
    newestViewFrustum.setEyeOffsetPosition(getCameraEyeOffsetPosition());

    // if there has been a change, then recalculate
    if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
        _currentViewFrustum = newestViewFrustum;
        _currentViewFrustum.calculate();
        currentViewFrustumChanged = true;
    }

    // Also check for LOD changes from the client
    if (_lodInitialized) {
        if (_lastClientBoundaryLevelAdjust != getBoundaryLevelAdjust()) {
            _lastClientBoundaryLevelAdjust = getBoundaryLevelAdjust();
            _lodChanged = true;
        }
        if (_lastClientOctreeSizeScale != getOctreeSizeScale()) {
            _lastClientOctreeSizeScale = getOctreeSizeScale();
            _lodChanged = true;
        }
    } else {
        _lodInitialized = true;
        _lastClientOctreeSizeScale = getOctreeSizeScale();
        _lastClientBoundaryLevelAdjust = getBoundaryLevelAdjust();
        _lodChanged = false;
    }

    // When we first detect that the view stopped changing, we record this.
    // but we don't change it back to false until we've completely sent this
    // scene.
    if (_viewFrustumChanging && !currentViewFrustumChanged) {
        _viewFrustumJustStoppedChanging = true;
    }
    _viewFrustumChanging = currentViewFrustumChanged;
    return currentViewFrustumChanged;
}
Пример #17
0
float KRViewport::coverage(const KRAABB &b) const
{
    if(!visible(b)) {
        return 0.0f; // Culled out by view frustrum
    } else {
        KRVector3 nearest_point = b.nearestPoint(getCameraPosition());
        float distance = (nearest_point - getCameraPosition()).magnitude();

        KRVector3 v = KRMat4::DotWDiv(m_matProjection, getCameraPosition() + getCameraDirection() * distance);

        float screen_depth = distance / 1000.0f;

        return KRCLAMP(1.0f - screen_depth, 0.01f, 1.0f);

        /*

        KRVector2 screen_min;
        KRVector2 screen_max;
        // Loop through all corners and transform them to screen space
        for(int i=0; i<8; i++) {
            KRVector3 screen_pos = KRMat4::DotWDiv(m_matViewProjection, KRVector3(i & 1 ? b.min.x : b.max.x, i & 2 ? b.min.y : b.max.y, i & 4 ? b.min.z : b.max.z));
            if(i==0) {
                screen_min = screen_pos.xy();
                screen_max = screen_pos.xy();
            } else {
                if(screen_pos.x < screen_min.x) screen_min.x = screen_pos.x;
                if(screen_pos.y < screen_min.y) screen_min.y = screen_pos.y;
                if(screen_pos.x > screen_max.x) screen_max.x = screen_pos.x;
                if(screen_pos.y > screen_max.y) screen_max.y = screen_pos.y;
            }
        }

        screen_min.x = KRCLAMP(screen_min.x, 0.0f, 1.0f);
        screen_min.y = KRCLAMP(screen_min.y, 0.0f, 1.0f);
        screen_max.x = KRCLAMP(screen_max.x, 0.0f, 1.0f);
        screen_max.y = KRCLAMP(screen_max.y, 0.0f, 1.0f);

        float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y);
        return KRCLAMP(c, 0.01f, 1.0f);
        */
    }
}
Пример #18
0
void mouseMotion(int x, int y) {
	if (MouseMode == MOUSE_MODE_SHOOTING)
	{
		character.updateArmAngle(mouseToCharacterWorldPlane(x, y));
	}
	else if (MouseMode == MOUSE_MODE_CAMERA)
	{
		// Pass this event to trackball.h
		tbMotionFunc(x, y);
		calculateWorldSpaceViewportBounds();
		camPos = getCameraPosition();
	}
}
Пример #19
0
// pour changement de taille ou desiconification
void reshape(int w, int h)
{
	W_fen = w;
	H_fen = h;

    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho (-1.1, 1.1, -1.1,1.1, -1000.0, 1000.0);
    gluPerspective (50, (float)w/h, 1, 10);
    glMatrixMode(GL_MODELVIEW);

	calculateWorldSpaceViewportBounds();
    LightPos[0] = topLeft[0]; //init light position
	camPos = getCameraPosition();
}
Пример #20
0
void	FractureDemo::shootBox(const btVector3& destination)
{

	if (m_dynamicsWorld)
	{
		btScalar mass = 1.f;
		btTransform startTransform;
		startTransform.setIdentity();
		btVector3 camPos = getCameraPosition();
		startTransform.setOrigin(camPos);

		setShootBoxShape ();

		btAssert((!m_shootBoxShape || m_shootBoxShape->getShapeType() != INVALID_SHAPE_PROXYTYPE));

		//rigidbody is dynamic if and only if mass is non zero, otherwise static
		bool isDynamic = (mass != 0.f);

		btVector3 localInertia(0,0,0);
		if (isDynamic)
			m_shootBoxShape->calculateLocalInertia(mass,localInertia);

		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects

		btFractureBody* body = new btFractureBody(mass,0,m_shootBoxShape,localInertia,&mass,1,m_dynamicsWorld);

		body->setWorldTransform(startTransform);

		m_dynamicsWorld->addRigidBody(body);


		body->setLinearFactor(btVector3(1,1,1));
		//body->setRestitution(1);

		btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
		linVel.normalize();
		linVel*=m_ShootBoxInitialSpeed;

		body->getWorldTransform().setOrigin(camPos);
		body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
		body->setLinearVelocity(linVel);
		body->setAngularVelocity(btVector3(0,0,0));
		body->setCcdMotionThreshold(1.);
		body->setCcdSweptSphereRadius(0.2f);

	}
}
Пример #21
0
void mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN &&
        MouseMode == MOUSE_MODE_SHOOTING)
    {
		Vec3Df shootingDirection = mouseToCharacterWorldPlane(x, y) - character.getAngleRefPos();
		spawnProjectile(shootingDirection);
		character.updateArmAngle(mouseToCharacterWorldPlane(x, y));
    }
    else if (MouseMode == MOUSE_MODE_CAMERA)
    {
        // Pass this event to trackball.h
        tbMouseFunc(button, state, x, y);
		calculateWorldSpaceViewportBounds();
		camPos = getCameraPosition();
    }
}
Пример #22
0
/**
 * modifie la position du joueur et celle de la caméra
 *
 * @param position          Nouvelle position du joueur
 */
void Player::setPosition(irr::core::vector3df position)
{
    boost::mutex::scoped_lock l(mutexPlayer);

    // Modifie la position du joueur
    this->position = position;
    lastPositionUpdate = getTime();
    viseurRay.start = position;         // Viseur

    // Modifie le mouseRay (on a déplacé la caméra)
    l.unlock();
    position = getCameraPosition();
    l.lock();
    mouseRay.start = position;

    // Met la rotation du joueur a jour
    l.unlock();
    updateViseurRay();
}
Пример #23
0
void AugmentedView::Update(Mat * rgbaImage, Engine * engine)
{	
	tabs->Draw(rgbaImage);

	if (!updateObjectMap.empty())
	{
		if (engine->communicator != NULL && engine->communicator->IsConnected())
		{
			for (map<string,ARObjectMessage*>::iterator it = updateObjectMap.begin();it != updateObjectMap.end();it++)
			{
				LOGD(LOGTAG_ARINPUT,"Sending update for object %s",(*it).first.c_str());
				engine->communicator->SendMessage((*it).second);
			}			
		}
		updateObjectMap.clear();		
	}

	
	if (createNext)
	{
		Point3f cameraPosition = getCameraPosition(projection);
		char objectName[100];
		sprintf(objectName,"user_obj_%d",objectVector.size()+1);
		GLObject * glObject = OpenGLHelper::CreateMultiColorCube(20);
		Point3f newLocation = Point3f(0,0,0);
		if (testObject != NULL)
			newLocation = testObject->position;

		ARObject * newObject = new ARObject(glObject, newLocation);
		newObject->BoundingSphereRadius = 12;
		newObject->objectID = objectName;
		if (engine->communicator->IsConnected())
		{
			engine->communicator->SendMessage(new ARObjectMessage(newObject,true));
		}
		createNext = false;
		objectVector.push_back(newObject);
	}

	canDraw = true;
}
Пример #24
0
void	CcdPhysicsDemo::shootBox(const btVector3& destination)
{

	if (m_dynamicsWorld)
	{
		float mass = 1.f;
		btTransform startTransform;
		startTransform.setIdentity();
		btVector3 camPos = getCameraPosition();
		startTransform.setOrigin(camPos);

		setShootBoxShape ();


		btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape);
		body->setLinearFactor(btVector3(1,1,1));
		//body->setRestitution(1);

		btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
		linVel.normalize();
		linVel*=m_ShootBoxInitialSpeed;

		body->getWorldTransform().setOrigin(camPos);
		body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
		body->setLinearVelocity(linVel);
		body->setAngularVelocity(btVector3(0,0,0));
		body->setContactProcessingThreshold(1e30);

		///when using m_ccdMode, disable regular CCD
		if (m_ccdMode==USE_CCD)
		{
			body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
			body->setCcdSweptSphereRadius(0.4f);
		}
		
	}
}
Пример #25
0
int MapView::calcLastVisibleFloor()
{
    if(!m_multifloor)
        return calcFirstVisibleFloor();

    int z = 7;

    Position cameraPosition = getCameraPosition();
    // this could happens if the player is not known yet
    if(cameraPosition.isValid()) {
        // view only underground floors when below sea level
        if(cameraPosition.z > Otc::SEA_FLOOR)
            z = cameraPosition.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
        else
            z = Otc::SEA_FLOOR;
    }

    if(m_lockedFirstVisibleFloor != -1)
        z = std::max(m_lockedFirstVisibleFloor, z);

    // just ensure the that the floor is in the valid range
    z = std::min(std::max(z, 0), (int)Otc::MAX_Z);
    return z;
}
Пример #26
0
void drawMoon()
{
	glUseProgram(planetShader);
	setupLighting(planetShader);
	vec3 Position = getCameraPosition();
	v = getViewMatrix();
	
	mat4 rt = multiplymat4(rotateY(orbitSpeedArray[3]), translate(planetInstanceArray[3].radius*1000, 0.0, 0.0));
	m = multiplymat4(multiplymat4(rt, translate(10.0, 0.0, 0.0)), scale(100));
	
	//mv = modelMatrices[i];
	initMVP(planetShader, m, v);
	glUniform3f(glGetUniformLocation(planetShader, "cameraPos"), Position.x, Position.y, Position.z);
    
    glBindVertexArray (planetVAO);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, planetInstanceArray[2].texture);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, planetInstanceArray[2].normal);
 	glUniform1i(glGetUniformLocation(planetShader, "tex"), 0);
    glUniform1i(glGetUniformLocation(planetShader, "normalTex"), 1);
    //glDrawArrays( GL_TRIANGLES, 0, planet.vertexNumber );
    glBindVertexArray(0);
}
void LLVOPartGroup::getGeometry(const LLViewerPart& part,
								LLStrider<LLVector4a>& verticesp)
{
	if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK)
	{
		LLVector4a axis, pos, paxis, ppos;
		F32 scale, pscale;

		pos.load3(part.mPosAgent.mV);
		axis.load3(part.mAxis.mV);
		scale = part.mScale.mV[0];
		
		if (part.mParent)
		{
			ppos.load3(part.mParent->mPosAgent.mV);
			paxis.load3(part.mParent->mAxis.mV);
			pscale = part.mParent->mScale.mV[0];
		}
		else
		{ //use source object as position
			
			if (part.mPartSourcep->mSourceObjectp.notNull())
			{
				LLVector3 v = LLVector3(0,0,1);
				v *= part.mPartSourcep->mSourceObjectp->getRenderRotation();
				paxis.load3(v.mV);
				ppos.load3(part.mPartSourcep->mPosAgent.mV);
				pscale = part.mStartScale.mV[0];
			}
			else
			{ //no source object, no parent, nothing to draw
				ppos = pos;
				pscale = scale;
				paxis = axis;
			}
		}

		LLVector4a p0, p1, p2, p3;

		scale *= 0.5f;
		pscale *= 0.5f;

		axis.mul(scale);
		paxis.mul(pscale);

		p0.setAdd(pos, axis);
		p1.setSub(pos,axis);
		p2.setAdd(ppos, paxis);
		p3.setSub(ppos, paxis);

		(*verticesp++) = p2;
		(*verticesp++) = p3;
		(*verticesp++) = p0;
		(*verticesp++) = p1;
	}
	else
	{
		LLVector4a part_pos_agent;
		part_pos_agent.load3(part.mPosAgent.mV);
		LLVector4a camera_agent;
	camera_agent.load3(getCameraPosition().mV); 
	LLVector4a at;
	at.setSub(part_pos_agent, camera_agent);
	LLVector4a up(0, 0, 1);
	LLVector4a right;

	right.setCross3(at, up);
	right.normalize3fast();
	up.setCross3(right, at);
	up.normalize3fast();

	if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
	{
		LLVector4a normvel;
		normvel.load3(part.mVelocity.mV);
		normvel.normalize3fast();
		LLVector2 up_fracs;
		up_fracs.mV[0] = normvel.dot3(right).getF32();
		up_fracs.mV[1] = normvel.dot3(up).getF32();
		up_fracs.normalize();
		LLVector4a new_up;
		LLVector4a new_right;

		//new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
		LLVector4a t = right;
		t.mul(up_fracs.mV[0]);
		new_up = up;
		new_up.mul(up_fracs.mV[1]);
		new_up.add(t);

		//new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
		t = right;
		t.mul(up_fracs.mV[1]);
		new_right = up;
		new_right.mul(up_fracs.mV[0]);
		t.sub(new_right);

		up = new_up;
		right = t;
		up.normalize3fast();
		right.normalize3fast();
	}

		right.mul(0.5f*part.mScale.mV[0]);
		up.mul(0.5f*part.mScale.mV[1]);


		//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should)
		// this works because there is actually a 4th float stored after the vertex position which is used as a texture index
		// also, somebody please VECTORIZE THIS

		LLVector4a ppapu;
		LLVector4a ppamu;

		ppapu.setAdd(part_pos_agent, up);
		ppamu.setSub(part_pos_agent, up);

		verticesp->setSub(ppapu, right);
		(*verticesp++).getF32ptr()[3] = 0.f;
		verticesp->setSub(ppamu, right);
		(*verticesp++).getF32ptr()[3] = 0.f;
		verticesp->setAdd(ppapu, right);
		(*verticesp++).getF32ptr()[3] = 0.f;
		verticesp->setAdd(ppamu, right);
		(*verticesp++).getF32ptr()[3] = 0.f;
	}
}
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(FTM_UPDATE_PARTICLES);

	dirtySpatialGroup();
	
	S32 num_parts = mViewerPartGroupp->getCount();
	LLFace *facep;
	LLSpatialGroup* group = drawable->getSpatialGroup();
	if (!group && num_parts)
	{
		drawable->movePartition();
		group = drawable->getSpatialGroup();
	}

	if (group && group->isVisible())
	{
		dirtySpatialGroup(TRUE);
	}

	if (!num_parts)
	{
		if (group && drawable->getNumFaces())
		{
			group->setState(LLSpatialGroup::GEOM_DIRTY);
		}
		drawable->setNumFaces(0, NULL, getTEImage(0));
		return TRUE;
	}

 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
	{
		return TRUE;
	}

	if (num_parts > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0));
	}

	F32 tot_area = 0;

	F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
	pixel_meter_ratio *= pixel_meter_ratio;

	LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;

	S32 count=0;
	mDepth = 0.f;
	S32 i = 0 ;
	LLVector3 camera_agent = getCameraPosition();
	
	F32 max_scale = 0.f;


	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
	{
		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];


		//remember the largest particle
		max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]);

		if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK)
		{ //include ribbon segment length in scale
			const LLVector3* pos_agent = NULL;
			if (part->mParent)
			{
				pos_agent = &(part->mParent->mPosAgent);
			}
			else if (part->mPartSourcep.notNull())
			{
				pos_agent = &(part->mPartSourcep->mPosAgent);
			}

			if (pos_agent)
			{
				F32 dist = (*pos_agent-part->mPosAgent).length();

				max_scale = llmax(max_scale, dist);
			}
		}

		LLVector3 part_pos_agent(part->mPosAgent);
		LLVector3 at(part_pos_agent - camera_agent);

		
		F32 camera_dist_squared = at.lengthSquared();
		F32 inv_camera_dist_squared;
		if (camera_dist_squared > 1.f)
			inv_camera_dist_squared = 1.f / camera_dist_squared;
		else
			inv_camera_dist_squared = 1.f;

		llassert(llfinite(inv_camera_dist_squared));
		llassert(!llisnan(inv_camera_dist_squared));

		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
		tot_area = llmax(tot_area, area);
 		
		if (tot_area > max_area)
		{
			break;
		}
	
		count++;

		facep = drawable->getFace(i);
		if (!facep)
		{
			LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL;
			continue;
		}

		facep->setTEOffset(i);
		const F32 NEAR_PART_DIST_SQ = 5.f*5.f;  // Only discard particles > 5 m from the camera
		const F32 MIN_PART_AREA = .005f*.005f;  // only less than 5 mm x 5 mm at 1 m from camera
		
		if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
		{
			facep->setSize(0, 0);
			continue;
		}

		facep->setSize(4, 6);
		
		facep->setViewerObject(this);

		if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
		{
			facep->setState(LLFace::FULLBRIGHT);
		}
		else
		{
			facep->clearState(LLFace::FULLBRIGHT);
		}

		facep->mCenterLocal = part->mPosAgent;
		facep->setFaceColor(part->mColor);
		facep->setTexture(part->mImagep);
			
		//check if this particle texture is replaced by a parcel media texture.
		if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) 
		{
			part->mImagep->getParcelMedia()->addMediaToFace(facep) ;
		}

		mPixelArea = tot_area * pixel_meter_ratio;
		const F32 area_scale = 10.f; // scale area to increase priority a bit
		facep->setVirtualSize(mPixelArea*area_scale);
	}
	for (i = count; i < drawable->getNumFaces(); i++)
	{
		LLFace* facep = drawable->getFace(i);
		if (!facep)
		{
			LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL;
			continue;
		}
		facep->setTEOffset(i);
		facep->setSize(0, 0);
	}

	//record max scale (used to stretch bounding box for visibility culling)
	
	mScale.set(max_scale, max_scale, max_scale);

	mDrawable->movePartition();
	return TRUE;
}
Пример #29
0
void MapView::draw(const Rect& rect)
{
    // update visible tiles cache when needed
    if(m_mustUpdateVisibleTilesCache || m_updateTilesPos > 0)
        updateVisibleTilesCache(m_mustUpdateVisibleTilesCache ? 0 : m_updateTilesPos);

    float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS;
    Position cameraPosition = getCameraPosition();

    int drawFlags = 0;
    if(m_viewMode == NEAR_VIEW)
        drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls |
                    Otc::DrawItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawMissiles | Otc::DrawAnimations;
    else
        drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems;

    Size tileSize = Size(1,1) * m_tileSize;
    if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) {
        m_framebuffer->bind();

        if(m_mustCleanFramebuffer) {
            Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize);
            g_painter->setColor(Color::black);
            g_painter->drawFilledRect(clearRect);
        }
        g_painter->setColor(Color::white);

        auto it = m_cachedVisibleTiles.begin();
        auto end = m_cachedVisibleTiles.end();
        for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) {
            while(it != end) {
                const TilePtr& tile = *it;
                Position tilePos = tile->getPosition();
                if(tilePos.z != z)
                    break;
                else
                    ++it;

                if(!m_drawMinimapColors)
                    tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags);
                else {
                    uint8 c = tile->getMinimapColorByte();
                    if(c == 0)
                        continue;

                    g_painter->setColor(Color::from8bit(c));
                    g_painter->drawFilledRect(Rect(transformPositionTo2D(tilePos, cameraPosition), tileSize));
                }
            }

            if(drawFlags & Otc::DrawMissiles && !m_drawMinimapColors) {
                for(const MissilePtr& missile : g_map.getFloorMissiles(z)) {
                    missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations);
                }
            }
        }

        m_framebuffer->release();

        // generating mipmaps each frame can be slow in older cards
        //m_framebuffer->getTexture()->buildHardwareMipmaps();

        m_mustDrawVisibleTilesCache = false;
    }


    Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize;
    if(isFollowingCreature())
        drawOffset += m_followingCreature->getWalkOffset() * scaleFactor;

    Size srcSize = rect.size();
    Size srcVisible = m_visibleDimension * m_tileSize;
    srcSize.scale(srcVisible, Fw::KeepAspectRatio);
    drawOffset.x += (srcVisible.width() - srcSize.width()) / 2;
    drawOffset.y += (srcVisible.height() - srcSize.height()) / 2;
    Rect srcRect = Rect(drawOffset, srcSize);

    g_painter->setColor(Color::white);
    glDisable(GL_BLEND);
    g_painter->setShaderProgram(m_shader);
#if 0
    // debug source area
    g_painter->saveAndResetState();
    m_framebuffer->bind();
    g_painter->setColor(Color::green);
    g_painter->drawBoundingRect(srcRect, 2);
    m_framebuffer->release();
    g_painter->restoreSavedState();
    m_framebuffer->draw(rect);
#else
    m_framebuffer->draw(rect, srcRect);
#endif
    g_painter->resetShaderProgram();
    glEnable(GL_BLEND);


    // this could happen if the player position is not known yet
    if(!cameraPosition.isValid())
        return;

    float horizontalStretchFactor = rect.width() / (float)srcRect.width();
    float verticalStretchFactor = rect.height() / (float)srcRect.height();

    // avoid drawing texts on map in far zoom outs
    if(m_viewMode == NEAR_VIEW && m_drawTexts) {
        for(const CreaturePtr& creature : m_cachedFloorVisibleCreatures) {
            Point creatureOffset = Point(16 - creature->getDisplacementX(), -3 - creature->getDisplacementY());
            Position pos = creature->getPosition();
            Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
            p += (creature->getDrawOffset() + creatureOffset) * scaleFactor;
            p.x = p.x * horizontalStretchFactor;
            p.y = p.y * verticalStretchFactor;
            p += rect.topLeft();

            creature->drawInformation(p, g_map.isCovered(pos, m_cachedFirstVisibleFloor), rect);
        }

        for(const StaticTextPtr& staticText : g_map.getStaticTexts()) {
            Position pos = staticText->getPosition();

            // ony draw static texts from current camera floor, unless yells
            //if(pos.z != cameraPosition.z && !staticText->isYell())
            //    continue;

            Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
            p.x = p.x * horizontalStretchFactor;
            p.y = p.y * verticalStretchFactor;
            p += rect.topLeft();
            staticText->drawText(p, rect);
        }

        for(const AnimatedTextPtr& animatedText : g_map.getAnimatedTexts()) {
            Position pos = animatedText->getPosition();

            // only draw animated texts from visible floors
            if(pos.z < m_cachedFirstVisibleFloor || pos.z > m_cachedLastVisibleFloor)
                continue;

            // dont draw animated texts from covered tiles
            if(pos.z != cameraPosition.z && g_map.isCovered(pos, m_cachedFirstVisibleFloor))
                continue;

            Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
            p.x = p.x * horizontalStretchFactor;
            p.y = p.y * verticalStretchFactor;
            p += rect.topLeft();
            animatedText->drawText(p, rect);
        }
    } else if(m_viewMode > NEAR_VIEW) {
        // draw a cross in the center instead of our creature
        /*
            Known Issue: Changing Z axis causes the cross to go off a little bit.
        */
        Rect vRect(0, 0, 2, 10);
        Rect hRect(0, 0, 10, 2);
        g_painter->setColor(Color::white);

        if(!m_follow && m_followingCreature)
        {
            Position pos = m_followingCreature->getPosition();
            Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
            p.x = p.x * horizontalStretchFactor;
            p.y = p.y * verticalStretchFactor;
            p += rect.topLeft();

            vRect.setX(p.x); vRect.setY(p.y - 4);
            hRect.setX(p.x - 4); hRect.setY(p.y);

            hRect.setWidth(10); hRect.setHeight(2);
            vRect.setWidth(2); vRect.setHeight(10);
        }
        else {
            vRect.moveCenter(rect.center());
            hRect.moveCenter(rect.center());
        }

        g_painter->drawFilledRect(vRect);
        g_painter->drawFilledRect(hRect);
    }
}
Пример #30
0
void MapView::updateVisibleTilesCache(int start)
{
    if(start == 0) {
        m_cachedFirstVisibleFloor = calcFirstVisibleFloor();
        m_cachedLastVisibleFloor = calcLastVisibleFloor();
        assert(m_cachedFirstVisibleFloor >= 0 && m_cachedLastVisibleFloor >= 0 &&
               m_cachedFirstVisibleFloor <= Otc::MAX_Z && m_cachedLastVisibleFloor <= Otc::MAX_Z);

        if(m_cachedLastVisibleFloor < m_cachedFirstVisibleFloor)
            m_cachedLastVisibleFloor = m_cachedFirstVisibleFloor;

        m_cachedFloorVisibleCreatures.clear();
        m_cachedVisibleTiles.clear();

        m_mustCleanFramebuffer = true;
        m_mustDrawVisibleTilesCache = true;
        m_mustUpdateVisibleTilesCache = false;
        m_updateTilesPos = 0;
    } else
        m_mustCleanFramebuffer = false;

    // there is no tile to render on invalid positions
    Position cameraPosition = getCameraPosition();
    if(!cameraPosition.isValid())
        return;

    bool stop = false;

    // clear current visible tiles cache
    m_cachedVisibleTiles.clear();
    m_mustDrawVisibleTilesCache = true;
    m_updateTilesPos = 0;

    // cache visible tiles in draw order
    // draw from last floor (the lower) to first floor (the higher)
    for(int iz = m_cachedLastVisibleFloor; iz >= m_cachedFirstVisibleFloor && !stop; --iz) {
        if(m_viewMode <= FAR_VIEW) {
            const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1;
            // loop through / diagonals beginning at top left and going to top right
            for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) {
                // loop current diagonal tiles
                int advance = std::max(diagonal - m_drawDimension.height(), 0);
                for(int iy = diagonal - advance, ix = advance; iy >= 0 && ix < m_drawDimension.width() && !stop; --iy, ++ix) {
                    // only start really looking tiles in the desired start
                    if(m_updateTilesPos < start) {
                        m_updateTilesPos++;
                        continue;
                    }

                    // avoid rendering too much tiles at once
                    if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS && m_viewMode >= HUGE_VIEW) {
                        stop = true;
                        break;
                    }

                    // position on current floor
                    //TODO: check position limits
                    Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y);
                    // adjust tilePos to the wanted floor
                    tilePos.coveredUp(cameraPosition.z - iz);
                    if(const TilePtr& tile = g_map.getTile(tilePos)) {
                        // skip tiles that have nothing
                        if(!tile->isDrawable())
                            continue;
                        // skip tiles that are completely behind another tile
                        if(g_map.isCompletelyCovered(tilePos, m_cachedFirstVisibleFloor))
                            continue;
                        m_cachedVisibleTiles.push_back(tile);
                    }
                    m_updateTilesPos++;
                }
            }
        } else {
            // cache tiles in spiral mode
            static std::vector<Point> m_spiral;
            if(start == 0) {
                m_spiral.resize(m_drawDimension.area());
                int width = m_drawDimension.width();
                int height = m_drawDimension.height();
                int tpx = width/2 - 2;
                int tpy = height/2 - 2;
                int count = 0;
                Rect area(0, 0, m_drawDimension);
                m_spiral[count++] = Point(tpx+1,tpy+1);
                for(int step = 1; tpx >= 0 || tpy >= 0; ++step, --tpx, --tpy) {
                    int qs = 2*step;
                    Rect lines[4] = {
                        Rect(tpx,       tpy,       qs,  1),
                        Rect(tpx + qs,  tpy,       1,   qs),
                        Rect(tpx +  1,  tpy + qs,  qs,  1),
                        Rect(tpx,       tpy + 1,   1,   qs),
                    };

                    for(int i=0;i<4;++i) {
                        int sx = std::max(lines[i].left(), area.left());
                        int ex = std::min(lines[i].right(), area.right());
                        int sy = std::max(lines[i].top(), area.top());
                        int ey = std::min(lines[i].bottom(), area.bottom());
                        for(int qx=sx;qx<=ex;++qx)
                            for(int qy=sy;qy<=ey;++qy)
                                m_spiral[count++] = Point(qx, qy);
                    }
                }
            }

            for(m_updateTilesPos = start; m_updateTilesPos < (int)m_spiral.size(); ++m_updateTilesPos) {
                // avoid rendering too much tiles at once
                if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS) {
                    stop = true;
                    break;
                }

                const Point& p = m_spiral[m_updateTilesPos];
                Position tilePos = cameraPosition.translated(p.x - m_virtualCenterOffset.x, p.y - m_virtualCenterOffset.y);
                tilePos.coveredUp(cameraPosition.z - iz);
                if(const TilePtr& tile = g_map.getTile(tilePos)) {
                    if(tile->isDrawable())
                        m_cachedVisibleTiles.push_back(tile);
                }
            }
        }
    }

    if(!stop) {
        m_updateTilesPos = 0;
        m_spiral.clear();
    }

    if(start == 0 && m_drawTexts && m_viewMode <= NEAR_VIEW)
        m_cachedFloorVisibleCreatures = g_map.getSpectators(cameraPosition, false);
}