<commit_before>/*
 Copyright (c) 2010, The Barbarian Group
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#include "cinder/app/AppCocoaTouch.h"
#include "cinder/app/AppImplCocoaTouch.h"
#include "cinder/Log.h"

namespace cinder { namespace app {

AppCocoaTouch*	AppCocoaTouch::sInstance = nullptr;

AppCocoaTouch::Settings()
	: AppBase::Settings(), mStatusBarEnabled( false )
{
	mPowerManagement = true;
	mHighDensityDisplayEnabled = true;
	mMultiTouchEnabled = true;
}

AppCocoaTouch::AppCocoaTouch()
	: AppBase()
{
	AppCocoaTouch::sInstance = this;

	auto settings = dynamic_cast<Settings *>( sSettingsFromMain );
	CI_ASSERT( settings );

	Platform::get()->setExecutablePath( getAppPath() );
	mImpl = [[AppImplCocoaTouch alloc] init:this settings:*settings];

	enablePowerManagement( settings->isPowerManagementEnabled() );
}

AppCocoaTouch::~AppCocoaTouch()
{
	[mImpl release];
	mImpl = nil;
}

void AppCocoaTouch::launch( const char *title, int argc, char * const argv[] )
{
	::UIApplicationMain( argc, const_cast<char**>( argv ), nil, ::NSStringFromClass( [AppDelegateImpl class] ) );
}

WindowRef AppCocoaTouch::createWindow( const Window::Format &format )
{
	return [mImpl createWindow:format];
}

WindowRef AppCocoaTouch::getWindow() const
{
	if( ! mImpl->mActiveWindow )
		throw cinder::app::ExcInvalidWindow();
	else
		return mImpl->mActiveWindow->mWindowRef;
}

size_t AppCocoaTouch::getNumWindows() const
{
	return mImpl->mWindows.size();
}

WindowRef AppCocoaTouch::getWindowIndex( size_t index ) const
{
	if( index >= getNumWindows() )
		throw cinder::app::ExcInvalidWindow();

	auto iter = mImpl->mWindows.begin();
	std::advance( iter, index );
	return (*iter)->mWindowRef;
}

InterfaceOrientation AppCocoaTouch::getOrientation() const
{
	UIInterfaceOrientation orientation = [[mImpl getDeviceWindow] interfaceOrientation];
	return [mImpl convertInterfaceOrientation:orientation];
}

InterfaceOrientation AppCocoaTouch::getWindowOrientation() const
{
	UIInterfaceOrientation orientation = [mImpl->mActiveWindow interfaceOrientation];
	return [mImpl convertInterfaceOrientation:orientation];
}

void AppCocoaTouch::enableProximitySensor()
{
	[UIDevice currentDevice].proximityMonitoringEnabled = YES;
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(proximityStateChange:)
		name:UIDeviceProximityStateDidChangeNotification object:nil];
}

void AppCocoaTouch::disableProximitySensor()
{
	[UIDevice currentDevice].proximityMonitoringEnabled = NO;
}

bool AppCocoaTouch::proximityIsClose() const
{
	return mImpl->mProximityStateIsClose;
}

void AppCocoaTouch::enableBatteryMonitoring()
{
	[UIDevice currentDevice].batteryMonitoringEnabled = YES;
	mImpl->mBatteryLevel = [UIDevice currentDevice].batteryLevel;
	mImpl->mIsUnplugged = [UIDevice currentDevice].batteryState == UIDeviceBatteryStateUnplugged;
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(batteryLevelChange:)
		name:UIDeviceBatteryLevelDidChangeNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(batteryStateChange:)
		name:UIDeviceBatteryStateDidChangeNotification object:nil];
}

void AppCocoaTouch::disableBatteryMonitoring()
{
	[UIDevice currentDevice].batteryMonitoringEnabled = NO;
}

float AppCocoaTouch::getBatteryLevel() const
{
	return mImpl->mBatteryLevel;
}

bool AppCocoaTouch::isUnplugged() const
{
	return mImpl->mIsUnplugged;
}

void AppCocoaTouch::showKeyboard( const KeyboardOptions &options )
{
	[mImpl showKeyboard:options];
}

bool AppCocoaTouch::isKeyboardVisible() const
{
	return [mImpl isKeyboardVisible];
}

void AppCocoaTouch::hideKeyboard()
{
	[mImpl hideKeyboard];
}

std::string	AppCocoaTouch::getKeyboardString() const
{
	return [mImpl getKeyboardString];
}

void AppCocoaTouch::setKeyboardString( const std::string &keyboardString )
{
	[mImpl setKeyboardString:keyboardString];
}

::UITextView* AppCocoaTouch::getKeyboardTextView() const
{
	return [mImpl getKeyboardTextView];
}

void AppCocoaTouch::showStatusBar( AppCocoaTouch::StatusBarAnimation animation )
{
	if( animation == StatusBarAnimation::FADE )
		[mImpl showStatusBar:UIStatusBarAnimationFade];
	else if( animation == StatusBarAnimation::SLIDE )
		[mImpl showStatusBar:UIStatusBarAnimationSlide];
	else
		[mImpl showStatusBar:UIStatusBarAnimationNone];
}

bool AppCocoaTouch::isStatusBarVisible() const
{
	return [UIApplication sharedApplication].statusBarHidden == NO;
}

void AppCocoaTouch::hideStatusBar( AppCocoaTouch::StatusBarAnimation animation )
{
	if( animation == StatusBarAnimation::FADE )
		[mImpl hideStatusBar:UIStatusBarAnimationFade];
	else if( animation == StatusBarAnimation::SLIDE )
		[mImpl hideStatusBar:UIStatusBarAnimationSlide];
	else
		[mImpl hideStatusBar:UIStatusBarAnimationNone];
}

//! Returns the maximum frame-rate the App will attempt to maintain.
float AppCocoaTouch::getFrameRate() const
{
	return 60.0f / mImpl->mAnimationFrameInterval;
}

//! Sets the maximum frame-rate the App will attempt to maintain.
void AppCocoaTouch::setFrameRate( float frameRate )
{
	[mImpl setFrameRate:frameRate];
}

bool AppCocoaTouch::isFullScreen() const
{
	return true;
}

void AppCocoaTouch::setFullScreen( bool fullScreen, const FullScreenOptions &options )
{
	// NO-OP
}

fs::path AppCocoaTouch::getAppPath() const
{
	return fs::path( [[[NSBundle mainBundle] bundlePath] UTF8String] );
}

void AppCocoaTouch::quit()
{
	return; // no effect on iOS
}

void AppCocoaTouch::enablePowerManagement( bool powerManagement )
{
	mPowerManagement = powerManagement;
	[mImpl updatePowerManagement];
}

void AppCocoaTouch::emitDidEnterBackground()
{
	mSignalDidEnterBackground();
}

void AppCocoaTouch::emitWillEnterForeground()
{
	mSignalWillEnterForeground();
}

void AppCocoaTouch::emitMemoryWarning()
{
	mSignalMemoryWarning();
}

uint32_t AppCocoaTouch::emitSupportedOrientations()
{
	return mSignalSupportedOrientations();
}

void AppCocoaTouch::emitWillRotate()
{
	mSignalWillRotate();
}

void AppCocoaTouch::emitDidRotate()
{
	mSignalDidRotate();
}

void AppCocoaTouch::emitKeyboardWillShow()
{
	mSignalKeyboardWillShow();
}

void AppCocoaTouch::emitKeyboardWillHide()
{
	mSignalKeyboardWillHide();
}

std::ostream& operator<<( std::ostream &lhs, const InterfaceOrientation &rhs )
{
	switch( rhs ) {
		case InterfaceOrientation::Portrait:			lhs << "Portrait";				break;
		case InterfaceOrientation::PortraitUpsideDown:	lhs << "PortraitUpsideDown";	break;
		case InterfaceOrientation::LandscapeLeft:		lhs << "LandscapeLeft";			break;
		case InterfaceOrientation::LandscapeRight:		lhs << "LandscapeRight";		break;
		default: lhs << "Error";
	}
	return lhs;
}

float getOrientationDegrees( InterfaceOrientation orientation )
{
	switch( orientation ) {
		case InterfaceOrientation::Portrait:			return 0.0f;
		case InterfaceOrientation::PortraitUpsideDown:	return 180.0f;
		case InterfaceOrientation::LandscapeLeft:		return 90.0f;
		case InterfaceOrientation::LandscapeRight:		return 270.0f;
		default: return 0.0f;
	}
}

} } // namespace cinder::app
<commit_msg>fix AppCocoaTouch compiler errors after merges<commit_after>/*
 Copyright (c) 2010, The Barbarian Group
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#include "cinder/app/AppCocoaTouch.h"
#include "cinder/app/AppImplCocoaTouch.h"
#include "cinder/Log.h"

namespace cinder { namespace app {

AppCocoaTouch*	AppCocoaTouch::sInstance = nullptr;

AppCocoaTouch::Settings::Settings()
	: AppBase::Settings(), mStatusBarEnabled( false )
{
	mPowerManagementEnabled = true;
	mHighDensityDisplayEnabled = true;
	mMultiTouchEnabled = true;
}

AppCocoaTouch::AppCocoaTouch()
	: AppBase()
{
	AppCocoaTouch::sInstance = this;

	auto settings = dynamic_cast<Settings *>( sSettingsFromMain );
	CI_ASSERT( settings );

	Platform::get()->setExecutablePath( getAppPath() );
	mImpl = [[AppImplCocoaTouch alloc] init:this settings:*settings];

	enablePowerManagement( settings->isPowerManagementEnabled() );
}

AppCocoaTouch::~AppCocoaTouch()
{
	[mImpl release];
	mImpl = nil;
}

void AppCocoaTouch::launch( const char *title, int argc, char * const argv[] )
{
	::UIApplicationMain( argc, const_cast<char**>( argv ), nil, ::NSStringFromClass( [AppDelegateImpl class] ) );
}

WindowRef AppCocoaTouch::createWindow( const Window::Format &format )
{
	return [mImpl createWindow:format];
}

WindowRef AppCocoaTouch::getWindow() const
{
	if( ! mImpl->mActiveWindow )
		throw cinder::app::ExcInvalidWindow();
	else
		return mImpl->mActiveWindow->mWindowRef;
}

size_t AppCocoaTouch::getNumWindows() const
{
	return mImpl->mWindows.size();
}

WindowRef AppCocoaTouch::getWindowIndex( size_t index ) const
{
	if( index >= getNumWindows() )
		throw cinder::app::ExcInvalidWindow();

	auto iter = mImpl->mWindows.begin();
	std::advance( iter, index );
	return (*iter)->mWindowRef;
}

InterfaceOrientation AppCocoaTouch::getOrientation() const
{
	UIInterfaceOrientation orientation = [[mImpl getDeviceWindow] interfaceOrientation];
	return [mImpl convertInterfaceOrientation:orientation];
}

InterfaceOrientation AppCocoaTouch::getWindowOrientation() const
{
	UIInterfaceOrientation orientation = [mImpl->mActiveWindow interfaceOrientation];
	return [mImpl convertInterfaceOrientation:orientation];
}

void AppCocoaTouch::enableProximitySensor()
{
	[UIDevice currentDevice].proximityMonitoringEnabled = YES;
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(proximityStateChange:)
		name:UIDeviceProximityStateDidChangeNotification object:nil];
}

void AppCocoaTouch::disableProximitySensor()
{
	[UIDevice currentDevice].proximityMonitoringEnabled = NO;
}

bool AppCocoaTouch::proximityIsClose() const
{
	return mImpl->mProximityStateIsClose;
}

void AppCocoaTouch::enableBatteryMonitoring()
{
	[UIDevice currentDevice].batteryMonitoringEnabled = YES;
	mImpl->mBatteryLevel = [UIDevice currentDevice].batteryLevel;
	mImpl->mIsUnplugged = [UIDevice currentDevice].batteryState == UIDeviceBatteryStateUnplugged;
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(batteryLevelChange:)
		name:UIDeviceBatteryLevelDidChangeNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:mImpl selector:@selector(batteryStateChange:)
		name:UIDeviceBatteryStateDidChangeNotification object:nil];
}

void AppCocoaTouch::disableBatteryMonitoring()
{
	[UIDevice currentDevice].batteryMonitoringEnabled = NO;
}

float AppCocoaTouch::getBatteryLevel() const
{
	return mImpl->mBatteryLevel;
}

bool AppCocoaTouch::isUnplugged() const
{
	return mImpl->mIsUnplugged;
}

void AppCocoaTouch::showKeyboard( const KeyboardOptions &options )
{
	[mImpl showKeyboard:options];
}

bool AppCocoaTouch::isKeyboardVisible() const
{
	return [mImpl isKeyboardVisible];
}

void AppCocoaTouch::hideKeyboard()
{
	[mImpl hideKeyboard];
}

std::string	AppCocoaTouch::getKeyboardString() const
{
	return [mImpl getKeyboardString];
}

void AppCocoaTouch::setKeyboardString( const std::string &keyboardString )
{
	[mImpl setKeyboardString:keyboardString];
}

::UITextView* AppCocoaTouch::getKeyboardTextView() const
{
	return [mImpl getKeyboardTextView];
}

void AppCocoaTouch::showStatusBar( AppCocoaTouch::StatusBarAnimation animation )
{
	if( animation == StatusBarAnimation::FADE )
		[mImpl showStatusBar:UIStatusBarAnimationFade];
	else if( animation == StatusBarAnimation::SLIDE )
		[mImpl showStatusBar:UIStatusBarAnimationSlide];
	else
		[mImpl showStatusBar:UIStatusBarAnimationNone];
}

bool AppCocoaTouch::isStatusBarVisible() const
{
	return [UIApplication sharedApplication].statusBarHidden == NO;
}

void AppCocoaTouch::hideStatusBar( AppCocoaTouch::StatusBarAnimation animation )
{
	if( animation == StatusBarAnimation::FADE )
		[mImpl hideStatusBar:UIStatusBarAnimationFade];
	else if( animation == StatusBarAnimation::SLIDE )
		[mImpl hideStatusBar:UIStatusBarAnimationSlide];
	else
		[mImpl hideStatusBar:UIStatusBarAnimationNone];
}

//! Returns the maximum frame-rate the App will attempt to maintain.
float AppCocoaTouch::getFrameRate() const
{
	return 60.0f / mImpl->mAnimationFrameInterval;
}

//! Sets the maximum frame-rate the App will attempt to maintain.
void AppCocoaTouch::setFrameRate( float frameRate )
{
	[mImpl setFrameRate:frameRate];
}

bool AppCocoaTouch::isFullScreen() const
{
	return true;
}

void AppCocoaTouch::setFullScreen( bool fullScreen, const FullScreenOptions &options )
{
	// NO-OP
}

fs::path AppCocoaTouch::getAppPath() const
{
	return fs::path( [[[NSBundle mainBundle] bundlePath] UTF8String] );
}

void AppCocoaTouch::quit()
{
	return; // no effect on iOS
}

void AppCocoaTouch::enablePowerManagement( bool powerManagement )
{
	mPowerManagement = powerManagement;
	[mImpl updatePowerManagement];
}

void AppCocoaTouch::emitDidEnterBackground()
{
	mSignalDidEnterBackground();
}

void AppCocoaTouch::emitWillEnterForeground()
{
	mSignalWillEnterForeground();
}

void AppCocoaTouch::emitMemoryWarning()
{
	mSignalMemoryWarning();
}

uint32_t AppCocoaTouch::emitSupportedOrientations()
{
	return mSignalSupportedOrientations();
}

void AppCocoaTouch::emitWillRotate()
{
	mSignalWillRotate();
}

void AppCocoaTouch::emitDidRotate()
{
	mSignalDidRotate();
}

void AppCocoaTouch::emitKeyboardWillShow()
{
	mSignalKeyboardWillShow();
}

void AppCocoaTouch::emitKeyboardWillHide()
{
	mSignalKeyboardWillHide();
}

std::ostream& operator<<( std::ostream &lhs, const InterfaceOrientation &rhs )
{
	switch( rhs ) {
		case InterfaceOrientation::Portrait:			lhs << "Portrait";				break;
		case InterfaceOrientation::PortraitUpsideDown:	lhs << "PortraitUpsideDown";	break;
		case InterfaceOrientation::LandscapeLeft:		lhs << "LandscapeLeft";			break;
		case InterfaceOrientation::LandscapeRight:		lhs << "LandscapeRight";		break;
		default: lhs << "Error";
	}
	return lhs;
}

float getOrientationDegrees( InterfaceOrientation orientation )
{
	switch( orientation ) {
		case InterfaceOrientation::Portrait:			return 0.0f;
		case InterfaceOrientation::PortraitUpsideDown:	return 180.0f;
		case InterfaceOrientation::LandscapeLeft:		return 90.0f;
		case InterfaceOrientation::LandscapeRight:		return 270.0f;
		default: return 0.0f;
	}
}

} } // namespace cinder::app
<|endoftext|>


<commit_before>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

#include <DMUtils/maths.hpp>
#include <DMUtils/sfml.hpp>

#include <Lightsystem/SpotLight.hpp>

namespace DMGDVT {
namespace LS {

    SpotLight::~SpotLight() {
	}

    SpotLight::SpotLight(const sf::Vector2f& p, float r, const sf::Color& c, bool iso) : SpotLight(p,r,c,0.0f,2.0f*M_PIf,1.0f,0.0f,1.0f,iso) {
    }

    SpotLight::SpotLight(const sf::Vector2f& p, float r, const sf::Color& c, float da, float sa, float i, float b, float lf, bool iso) : Light(p,c,iso),
     _radius(r), _directionAngle(DMUtils::maths::degToRad(da)), _spreadAngle(sa), _bleed(b), _linearity(lf), _negative(false), _resizeWhenIncrease(false) {
        setSpreadAngle(sa);
        setIntensity(i);
        computeAABB();

        //32 points for a full circle, so we keep same spacing
        if(_spreadAngle > M_PIf * 3.0f/4.0f) _precision = 32;
        else if(_spreadAngle > M_PIf) _precision = 16;
        else if (_spreadAngle < M_PIf/2.0f) _precision = 4;
        else _precision = 8;
    }

    void SpotLight::preRender(sf::Shader* shader) {

        _negative = (_intensity<0.0f);

        if(shader==nullptr) return; //oopsie, can't work without the shader

        const float diam = _radius*2.0f;

        if(_renderTexture==nullptr) _renderTexture = new sf::RenderTexture();

        bool resizeTexture = false;

        if(_resizeWhenIncrease && _renderTexture->getSize().x < diam) resizeTexture = true;
        else if(_renderTexture->getSize().x != diam) resizeTexture = true;

        if(resizeTexture && !_renderTexture->create(diam,diam)) {
            delete _renderTexture;
            _renderTexture=nullptr;
            return; //somehow texture failed, maybe too big, abort
        }

        sf::Vector2f center(_renderTexture->getSize().x/2.0f,_renderTexture->getSize().y/2.0f);

        _renderTexture->clear();
        _render(*_renderTexture,sf::RenderStates::Default,shader,center);
        _renderTexture->display();

        _sprite.setOrigin(center);
        _sprite.setPosition(_position);
        _sprite.setTexture(_renderTexture->getTexture());
        _sprite.setRotation(DMUtils::maths::radToDeg(_directionAngle));

        computeAABB();
    }

    void SpotLight::render(const sf::IntRect& screen, sf::RenderTarget& target, sf::Shader* shader, const sf::RenderStates &states) {
        if(_intensity == 0.0f) return;
        if(!isActive()) return;

        if(_renderTexture!=nullptr) {
            target.draw(_sprite,states);
        } else {
            sf::Vector2f newCenter = _position - sf::Vector2f(screen.left,screen.top);
            _render(target,states,shader,sf::Vector2f(newCenter.x,screen.height - newCenter.y),_position,sf::Vector2f(_radius,_radius),DMUtils::maths::radToDeg(_directionAngle));
        }
	}

    void SpotLight::debugRender(sf::RenderTarget& target, const sf::RenderStates &states) {
        if(_intensity == 0.0f) return;
        if(!isActive()) return;

        if(_spreadAngle == M_PIf*2.0f) {
            sf::CircleShape shape(_radius);
            shape.setPosition(_position);
            shape.setOrigin(sf::Vector2f(1,1)*_radius);
            shape.setFillColor(_color);

            target.draw(shape,states);
        } else {
            sf::ConvexShape shape;
            shape.setPointCount(4);
            shape.setFillColor(sf::Color(_color.r,_color.g,_color.b,125));
            sf::Vector2f v(0,_radius);
            //*
            shape.setPosition(_position);shape.setPointCount(_precision+1);
            shape.setPoint(0,sf::Vector2f(0,0));

            float deltaAngle = _spreadAngle / (float)(_precision-1);
            for(int i=0;i<_precision;++i) {
                float angle = - _spreadAngle/2.0f + (float)i*deltaAngle;
                shape.setPoint(i+1,DMUtils::sfml::rotate(shape.getPoint(0)+sf::Vector2f(0.0f,_radius),angle,shape.getPoint(0)));
            }

            shape.setRotation(DMUtils::maths::radToDeg(_directionAngle));

            target.draw(shape,states);
        }
	}

    void SpotLight::computeAABB() {

        if(_spreadAngle == M_PIf*2.0f) {
            _aabb.left = -_radius;
            _aabb.top = -_radius;
            _aabb.width = _aabb.height = _radius*2.0f;
        } else {
            // @TODO : move the rotation function to a real good DMGDVT::sfUtils folder
            sf::Vector2f v = DMUtils::sfml::rotate<float>(sf::Vector2f(0.0,_radius),_directionAngle);
            sf::Vector2f left = DMUtils::sfml::rotate<float>(v,-_spreadAngle/2.0f,_directionAngle);
            sf::Vector2f right = DMUtils::sfml::rotate<float>(v,_spreadAngle/2.0f,_directionAngle);

            int xmin = DMUtils::maths::min<float>(v.x, left.x, right.x, 0.0f);
            int xmax = DMUtils::maths::max<float>(v.x, left.x, right.x, 0.0f);
            int ymin = DMUtils::maths::min<float>(v.y, left.y, right.y, 0.0f);
            int ymax = DMUtils::maths::max<float>(v.y, left.y, right.y, 0.0f);

            _aabb.left = xmin;
            _aabb.top = ymin;
            _aabb.width = xmax - xmin;
            _aabb.height = ymax - ymin;
        }
    }

    bool SpotLight::isNegative() const {
        return _negative;
    }

    void SpotLight::setRadius(float r) {
        _radius = r;
	}

    float SpotLight::getRadius() const {
        return _radius;
	}

    void SpotLight::setDirectionAngle(float da) {
        _directionAngle = da;
        _sprite.setRotation(DMUtils::maths::radToDeg(_directionAngle));

        computeAABB();
	}

    float SpotLight::getDirectionAngle() const {
        return DMUtils::maths::radToDeg(_directionAngle);
	}

    void SpotLight::rotate(float delta) {
        float a =  _directionAngle + DMUtils::maths::degToRad(delta);
        while(a > 2.0*M_PIf) a -= 2.0*M_PIf;
        while(a < 0) a += 2.0*M_PIf;
        setDirectionAngle(a);
    }

    void SpotLight::setSpreadAngle(float sa) {
        sa = DMUtils::maths::degToRad(sa);
        if(sa<0) sa = -sa;
        while(sa > 2.0f*M_PIf) sa = 2.0f*M_PIf;
        _spreadAngle = sa;
    }

    float SpotLight::getSpreadAngle() const {
        return DMUtils::maths::radToDeg(_spreadAngle);
    }

    void SpotLight::setIntensity(float i) {
        _intensity = DMUtils::maths::clamp(i,-1.0f,1.0f);;
	}

    float SpotLight::getIntensity() const {
        return DMUtils::maths::abs(_intensity);
	}

    void SpotLight::setBleed(float b) {
        _bleed = b;
	}

    float SpotLight::getBleed() const {
        return _bleed;
	}

    void SpotLight::setLinearity(float lf) {
        _linearity = lf;
	}

    float SpotLight::getLinearity() const {
        return _linearity;
	}

    void SpotLight::setPrecision(int p) {
        _precision = p;
    }

    int SpotLight::getPrecision() const {
        return _precision;
    }

    bool SpotLight::getResizeWhenIncrease() const {
        return _resizeWhenIncrease;
    }

    void SpotLight::setResizeWhenIncrease(bool r) {
        _resizeWhenIncrease = r;
    }

	/*** PROTECTED ***/

	void SpotLight::_render(sf::RenderTarget& target, const sf::RenderStates& states, sf::Shader* shader, sf::Vector2f center, sf::Vector2f shapePosition, sf::Vector2f shapeOrigin, float shapeRotation) {

        float r = _color.r * DMUtils::maths::abs(_intensity);
        float g = _color.g * DMUtils::maths::abs(_intensity);
        float b = _color.b * DMUtils::maths::abs(_intensity);
        sf::Color c(r,g,b,255);

        sf::RenderStates st(states);
        st.shader = shader;

        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_CENTER,center);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_RADIUS,_radius);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_COLOR,c);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_BLEED,_bleed);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_LINEARITY,_linearity);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_ISOMETRIC,_isometric);

        sf::ConvexShape shape;

        if(_spreadAngle==M_PIf*2.0f) {

            float diam = _radius*2.0f;

            shape.setPointCount(4);
            shape.setPoint(0,sf::Vector2f(0.0f,0.0f));
            shape.setPoint(1,sf::Vector2f(diam,0.0f));
            shape.setPoint(2,sf::Vector2f(diam,diam));
            shape.setPoint(3,sf::Vector2f(0.0f,diam));

        } else {

            float deltaAngle = _spreadAngle / (float)(_precision-1);

            shape.setPointCount(_precision+1);
            shape.setPoint(0,sf::Vector2f(_radius,_radius));

            for(int i=0;i<_precision;++i) {
                float angle = - _spreadAngle/2.0f + (float)i*deltaAngle;
                shape.setPoint(i+1,DMUtils::sfml::rotate(shape.getPoint(0)+sf::Vector2f(0.0f,_radius),angle,shape.getPoint(0)));
            }

            shape.setRotation(shapeRotation);
        }
        shape.setPosition(shapePosition);
        shape.setOrigin(shapeOrigin);
        target.draw(shape,st);
	}

}
}
<commit_msg>Corrected debug render & added code to draw target line<commit_after>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

#include <DMUtils/maths.hpp>
#include <DMUtils/sfml.hpp>

#include <Lightsystem/SpotLight.hpp>

namespace DMGDVT {
namespace LS {

    SpotLight::~SpotLight() {
	}

    SpotLight::SpotLight(const sf::Vector2f& p, float r, const sf::Color& c, bool iso) : SpotLight(p,r,c,0.0f,2.0f*M_PIf,1.0f,0.0f,1.0f,iso) {
    }

    SpotLight::SpotLight(const sf::Vector2f& p, float r, const sf::Color& c, float da, float sa, float i, float b, float lf, bool iso) : Light(p,c,iso),
     _radius(r), _directionAngle(DMUtils::maths::degToRad(da)), _spreadAngle(sa), _bleed(b), _linearity(lf), _negative(false), _resizeWhenIncrease(false) {
        setSpreadAngle(sa);
        setIntensity(i);
        computeAABB();

        //32 points for a full circle, so we keep same spacing
        if(_spreadAngle > M_PIf * 3.0f/4.0f) _precision = 32;
        else if(_spreadAngle > M_PIf) _precision = 16;
        else if (_spreadAngle < M_PIf/2.0f) _precision = 4;
        else _precision = 8;
    }

    void SpotLight::preRender(sf::Shader* shader) {

        _negative = (_intensity<0.0f);

        if(shader==nullptr) return; //oopsie, can't work without the shader

        const float diam = _radius*2.0f;

        if(_renderTexture==nullptr) _renderTexture = new sf::RenderTexture();

        bool resizeTexture = false;

        if(_resizeWhenIncrease && _renderTexture->getSize().x < diam) resizeTexture = true;
        else if(_renderTexture->getSize().x != diam) resizeTexture = true;

        if(resizeTexture && !_renderTexture->create(diam,diam)) {
            delete _renderTexture;
            _renderTexture=nullptr;
            return; //somehow texture failed, maybe too big, abort
        }

        sf::Vector2f center(_renderTexture->getSize().x/2.0f,_renderTexture->getSize().y/2.0f);

        _renderTexture->clear();
        _render(*_renderTexture,sf::RenderStates::Default,shader,center);
        _renderTexture->display();

        _sprite.setOrigin(center);
        _sprite.setPosition(_position);
        _sprite.setTexture(_renderTexture->getTexture());
        _sprite.setRotation(DMUtils::maths::radToDeg(_directionAngle));

        computeAABB();
    }

    void SpotLight::render(const sf::IntRect& screen, sf::RenderTarget& target, sf::Shader* shader, const sf::RenderStates &states) {
        if(_intensity == 0.0f) return;
        if(!isActive()) return;

        if(_renderTexture!=nullptr) {
            target.draw(_sprite,states);
        } else {
            sf::Vector2f newCenter = _position - sf::Vector2f(screen.left,screen.top);
            _render(target,states,shader,sf::Vector2f(newCenter.x,screen.height - newCenter.y),_position,sf::Vector2f(_radius,_radius),DMUtils::maths::radToDeg(_directionAngle));
        }
	}

    void SpotLight::debugRender(sf::RenderTarget& target, const sf::RenderStates &states) {
        if(_intensity == 0.0f) return;
        if(!isActive()) return;

        if(_spreadAngle == M_PIf*2.0f) {
            sf::CircleShape shape(_radius);
            shape.setPosition(_position);
            shape.setOrigin(sf::Vector2f(1,1)*_radius);
            shape.setFillColor(_color);
            if(isIsometric()) shape.setScale(1.0f,0.5f);
            target.draw(shape,states);
        } else {
            sf::ConvexShape shape;
            shape.setPointCount(4);
            shape.setFillColor(sf::Color(_color.r,_color.g,_color.b,125));
            sf::Vector2f v(0,_radius);
            //*
            shape.setPosition(_position);shape.setPointCount(_precision+1);
            shape.setPoint(0,sf::Vector2f(0,0));

            float deltaAngle = _spreadAngle / (float)(_precision-1);
            for(int i=0;i<_precision;++i) {
                float angle = _directionAngle - _spreadAngle/2.0f + (float)i*deltaAngle;
                sf::Vector2f p(DMUtils::sfml::rotate(shape.getPoint(0)+sf::Vector2f(0.0f,_radius),angle,shape.getPoint(0)));
                if(isIsometric()) {
                    p.y /= 2.0f;
                }
                shape.setPoint(i+1,p);
            }

            target.draw(shape,states);

            /*//draws the target angle
            sf::Vertex line[2];
            line[0].position = _position + sf::Vector2f(0.0f,0.0f);
            line[0].color = _color;
            line[1].position = _position +  DMUtils::sfml::rotate(v,_directionAngle);
            line[1].color = _color;

            if(isIsometric()) {
                line[1].position.y -= (line[1].position.y-_position.y)/2.0f;
            }

            target.draw(line,2,sf::Lines, states);*/
        }
	}

    void SpotLight::computeAABB() {

        if(_spreadAngle == M_PIf*2.0f) {
            _aabb.left = -_radius;
            _aabb.top = -_radius;
            _aabb.width = _aabb.height = _radius*2.0f;
        } else {
            // @TODO : move the rotation function to a real good DMGDVT::sfUtils folder
            sf::Vector2f v = DMUtils::sfml::rotate<float>(sf::Vector2f(0.0,_radius),_directionAngle);
            sf::Vector2f left = DMUtils::sfml::rotate<float>(v,-_spreadAngle/2.0f,_directionAngle);
            sf::Vector2f right = DMUtils::sfml::rotate<float>(v,_spreadAngle/2.0f,_directionAngle);

            int xmin = DMUtils::maths::min<float>(v.x, left.x, right.x, 0.0f);
            int xmax = DMUtils::maths::max<float>(v.x, left.x, right.x, 0.0f);
            int ymin = DMUtils::maths::min<float>(v.y, left.y, right.y, 0.0f);
            int ymax = DMUtils::maths::max<float>(v.y, left.y, right.y, 0.0f);

            _aabb.left = xmin;
            _aabb.top = ymin;
            _aabb.width = xmax - xmin;
            _aabb.height = ymax - ymin;
        }
    }

    bool SpotLight::isNegative() const {
        return _negative;
    }

    void SpotLight::setRadius(float r) {
        _radius = r;
	}

    float SpotLight::getRadius() const {
        return _radius;
	}

    void SpotLight::setDirectionAngle(float da) {
        _directionAngle = da;
        _sprite.setRotation(DMUtils::maths::radToDeg(_directionAngle));

        computeAABB();
	}

    float SpotLight::getDirectionAngle() const {
        return DMUtils::maths::radToDeg(_directionAngle);
	}

    void SpotLight::rotate(float delta) {
        float a =  _directionAngle + DMUtils::maths::degToRad(delta);
        while(a > 2.0*M_PIf) a -= 2.0*M_PIf;
        while(a < 0) a += 2.0*M_PIf;
        setDirectionAngle(a);
    }

    void SpotLight::setSpreadAngle(float sa) {
        sa = DMUtils::maths::degToRad(sa);
        if(sa<0) sa = -sa;
        while(sa > 2.0f*M_PIf) sa = 2.0f*M_PIf;
        _spreadAngle = sa;
    }

    float SpotLight::getSpreadAngle() const {
        return DMUtils::maths::radToDeg(_spreadAngle);
    }

    void SpotLight::setIntensity(float i) {
        _intensity = DMUtils::maths::clamp(i,-1.0f,1.0f);;
	}

    float SpotLight::getIntensity() const {
        return DMUtils::maths::abs(_intensity);
	}

    void SpotLight::setBleed(float b) {
        _bleed = b;
	}

    float SpotLight::getBleed() const {
        return _bleed;
	}

    void SpotLight::setLinearity(float lf) {
        _linearity = lf;
	}

    float SpotLight::getLinearity() const {
        return _linearity;
	}

    void SpotLight::setPrecision(int p) {
        _precision = p;
    }

    int SpotLight::getPrecision() const {
        return _precision;
    }

    bool SpotLight::getResizeWhenIncrease() const {
        return _resizeWhenIncrease;
    }

    void SpotLight::setResizeWhenIncrease(bool r) {
        _resizeWhenIncrease = r;
    }

	/*** PROTECTED ***/

	void SpotLight::_render(sf::RenderTarget& target, const sf::RenderStates& states, sf::Shader* shader, sf::Vector2f center, sf::Vector2f shapePosition, sf::Vector2f shapeOrigin, float shapeRotation) {

        float r = _color.r * DMUtils::maths::abs(_intensity);
        float g = _color.g * DMUtils::maths::abs(_intensity);
        float b = _color.b * DMUtils::maths::abs(_intensity);
        sf::Color c(r,g,b,255);

        sf::RenderStates st(states);
        st.shader = shader;

        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_CENTER,center);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_RADIUS,_radius);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_COLOR,c);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_BLEED,_bleed);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_LINEARITY,_linearity);
        shader->setParameter(DMGDVT::LS::Light::LAS_PARAM_ISOMETRIC,_isometric);

        sf::ConvexShape shape;

        if(_spreadAngle==M_PIf*2.0f) {

            float diam = _radius*2.0f;

            shape.setPointCount(4);
            shape.setPoint(0,sf::Vector2f(0.0f,0.0f));
            shape.setPoint(1,sf::Vector2f(diam,0.0f));
            shape.setPoint(2,sf::Vector2f(diam,diam));
            shape.setPoint(3,sf::Vector2f(0.0f,diam));

        } else {

            float deltaAngle = _spreadAngle / (float)(_precision-1);

            shape.setPointCount(_precision+1);
            shape.setPoint(0,sf::Vector2f(_radius,_radius));

            for(int i=0;i<_precision;++i) {
                float angle = - _spreadAngle/2.0f + (float)i*deltaAngle;
                shape.setPoint(i+1,DMUtils::sfml::rotate(shape.getPoint(0)+sf::Vector2f(0.0f,_radius),angle,shape.getPoint(0)));
            }

            shape.setRotation(shapeRotation);
        }
        shape.setPosition(shapePosition);
        shape.setOrigin(shapeOrigin);
        target.draw(shape,st);
	}

}
}
<|endoftext|>


<commit_before>#include "FPSController.h"
#include "Game.h"
#include "Params.h"
#include "Utils.h"

using namespace BGE;

FPSController::FPSController(void)
{
}

bool FPSController::Initialise()
{
	return GameComponent::Initialise();
}

FPSController::~FPSController(void)
{
}

void FPSController::Update()
{
	const Uint8 * keyState = Game::Instance()->GetKeyState();

	float moveSpeed = speed;

	if (keyState[SDL_SCANCODE_LSHIFT])
	{
		moveSpeed *= 10.0f;
	}

	if (keyState[SDL_SCANCODE_W])
	{
		transform->Walk(moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_S])
	{
		transform->Walk(-moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_A])
	{
		transform->Strafe(-moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_D])
	{
		transform->Strafe(moveSpeed * Time::deltaTime);
	}

	int x, y;
	int midX, midY;
	SDL_GetMouseState(&x,&y);
	midX = Params::GetFloat("width") / 2;
	midY = Params::GetFloat("height") / 2;
	float yaw, pitch;
	yaw = midX - x;
	pitch = midY - y;

	float scale = 0.1f;
	if (yaw != 0)
	{
		transform->Yaw(yaw * scale);
	}
	if (pitch != 0)
	{
		transform->Pitch(pitch * scale);
	}
	SDL_WarpMouseInWindow(
		Game::Instance()->GetMainWindow()
		,midX
		,midY
		);
	GameComponent::Update();
	//Controller::Update(this, this->parent);
}
<commit_msg>Change mouse behaviour. Will now work in other windows while game is running. Is still centered in game window when focused<commit_after>#include "FPSController.h"
#include "Game.h"
#include "Params.h"
#include "Utils.h"

using namespace BGE;

FPSController::FPSController(void)
{
}

bool FPSController::Initialise()
{
	return GameComponent::Initialise();
}

FPSController::~FPSController(void)
{
}

void FPSController::Update()
{
	const Uint8 * keyState = Game::Instance()->GetKeyState();

	float moveSpeed = speed;

	if (keyState[SDL_SCANCODE_LSHIFT])
	{
		moveSpeed *= 10.0f;
	}

	if (keyState[SDL_SCANCODE_W])
	{
		transform->Walk(moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_S])
	{
		transform->Walk(-moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_A])
	{
		transform->Strafe(-moveSpeed * Time::deltaTime);
	}

	if (keyState[SDL_SCANCODE_D])
	{
		transform->Strafe(moveSpeed * Time::deltaTime);
	}

	int x, y;
	int midX, midY;
	SDL_GetMouseState(&x,&y);
	midX = Params::GetFloat("width") / 2;
	midY = Params::GetFloat("height") / 2;
	float yaw, pitch;
	yaw = midX - x;
	pitch = midY - y;

	float scale = 0.1f;
	if (yaw != 0)
	{
		transform->Yaw(yaw * scale);
	}
	if (pitch != 0)
	{
		transform->Pitch(pitch * scale);
	}
	SDL_WarpMouseInWindow(
		NULL
		,midX
		,midY
		);
	GameComponent::Update();
	//Controller::Update(this, this->parent);
}
<|endoftext|>


<commit_before>/*
 Copyright (c) 2010, The Barbarian Group
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this list of conditions and
 the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#if defined( CINDER_COCOA ) && ( ! defined( __OBJC__ ) )
#	error "This file must be compiled as Objective-C++ on the Mac"
#endif

#include "cinder/qtime/MovieWriter.h"
#include "cinder/qtime/QuickTimeUtils.h"

#if defined( CINDER_MAC )
	#include <QTKit/QTKit.h>
	#include "cinder/cocoa/CinderCocoa.h"
#else
	#pragma push_macro( "__STDC_CONSTANT_MACROS" )
		#undef __STDC_CONSTANT_MACROS
		#include <QTML.h>
		#include <CVPixelBuffer.h>
		#include <ImageCompression.h>
		#include <Movies.h>
		#include <CoreFoundation/CFBase.h>
	#pragma pop_macro( "__STDC_CONSTANT_MACROS" )
#endif

namespace cinder { namespace qtime {

MovieWriter::MovieWriter( const std::string &outPath, int32_t width, int32_t height, MovieWriterCodecType codec, MovieWriterQuality quality )
	: mObj( shared_ptr<Obj>( new Obj( outPath, width, height, codec, quality ) ) )
{
}

MovieWriter::Obj::~Obj()
{
	if( ! mFinished )
		finish();
}

MovieWriter::Obj::Obj( const std::string &path, int32_t width, int32_t height, MovieWriterCodecType codec, MovieWriterQuality quality )
	: mPath( path ), mQuality( quality ), mWidth( width ), mHeight( height ), mFinished( false )
{
    OSErr       err = noErr;
    Handle      dataRef;
    OSType      dataRefType;

	startQuickTime();

    //Create movie file
	CFStringRef strDestMoviePath = ::CFStringCreateWithCString( kCFAllocatorDefault, path.c_str(), kCFStringEncodingUTF8 );
	err = ::QTNewDataReferenceFromFullPathCFString( strDestMoviePath, kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType );
	::CFRelease( strDestMoviePath );
	if( err )
        throw MovieWriterExcInvalidPath();

	// Create a movie for this file (data ref)
    err = ::CreateMovieStorage( dataRef, dataRefType, 'TVOD', smCurrentScript, createMovieFileDeleteCurFile, &mDataHandler, &mMovie );
	::DisposeHandle( dataRef );
    if( err )
        throw MovieWriterExc();

	mTrack = ::NewMovieTrack( mMovie, width << 16, height << 16, 0 );
	err = ::GetMoviesError();
	if( err )
		throw MovieWriterExc();

	//Create track media
	::TimeScale timescale = 1000;
	mMedia = ::NewTrackMedia( mTrack, ::VideoMediaType, timescale, 0, 0 );
	err = GetMoviesError();
	if( err )
		throw MovieWriterExc();

	//Prepare media for editing
	err = ::BeginMediaEdits( mMedia );
mCodec = 'jpeg';
	createCompressionSession();
	mCurrentTimeValue = 0;
}

void MovieWriter::Obj::addFrame( const ImageSourceRef &imageSource )
{
	CVPixelBufferRef pixelBuffer = createCvPixelBuffer( imageSource );

	ICMValidTimeFlags validTimeFlags = kICMValidTime_DisplayTimeStampIsValid | kICMValidTime_DisplayDurationIsValid;
	ICMCompressionFrameOptionsRef frameOptions = NULL;
	OSStatus err = ::ICMCompressionSessionEncodeFrame( mCompressionSession, pixelBuffer,
				mCurrentTimeValue, 60, validTimeFlags,
                frameOptions, NULL, NULL );
	mCurrentTimeValue += 60;
	if( err )
		MovieWriterExcFrameEncode();
}

extern "C" {
OSStatus MovieWriter::Obj::encodedFrameOutputCallback( void *refCon,
                   ICMCompressionSessionRef session,
                   OSStatus err,
                   ICMEncodedFrameRef encodedFrame,
                   void *reserved )
{
	MovieWriter::Obj *obj = reinterpret_cast<MovieWriter::Obj*>( refCon );
	OSStatus result = ::AddMediaSampleFromEncodedFrame( obj->mMedia, encodedFrame, NULL );
	return result;
}

}

void MovieWriter::Obj::createCompressionSession()
{
	OSStatus err = noErr;
	::ICMEncodedFrameOutputRecord encodedFrameOutputRecord = {0};
	::ICMCompressionSessionOptionsRef sessionOptions = NULL;

	err = ::ICMCompressionSessionOptionsCreate( NULL, &sessionOptions );
	if( err )
		goto bail;

	// We must set this flag to enable P or B frames.
	err = ::ICMCompressionSessionOptionsSetAllowTemporalCompression( sessionOptions, true );
	if( err )
		goto bail;

	// We must set this flag to enable B frames.
	err = ::ICMCompressionSessionOptionsSetAllowFrameReordering( sessionOptions, true );
	if( err )
		goto bail;

	// Set the maximum key frame interval, also known as the key frame rate.
	err = ::ICMCompressionSessionOptionsSetMaxKeyFrameInterval( sessionOptions, 30 );
	if( err )
		goto bail;

	// This allows the compressor more flexibility (ie, dropping and coalescing frames).
	err = ::ICMCompressionSessionOptionsSetAllowFrameTimeChanges( sessionOptions, true );
	if( err )
		goto bail;

	// We need durations when we store frames.
	err = ::ICMCompressionSessionOptionsSetDurationsNeeded( sessionOptions, true );
	if( err )
		goto bail;

	// Set the average data rate.
	/*err = ICMCompressionSessionOptionsSetProperty( sessionOptions,
				kQTPropertyClass_ICMCompressionSessionOptions,
				kICMCompressionSessionOptionsPropertyID_AverageDataRate,
				sizeof( averageDataRate ),
				&averageDataRate );*/
	if( err )
		goto bail;

	encodedFrameOutputRecord.encodedFrameOutputCallback = encodedFrameOutputCallback;
	encodedFrameOutputRecord.encodedFrameOutputRefCon = this;
	encodedFrameOutputRecord.frameDataAllocator = NULL;

	::TimeScale timeScale = 1000;
	err = ::ICMCompressionSessionCreate( NULL, mWidth, mHeight, mCodec, timeScale,
			sessionOptions, NULL, &encodedFrameOutputRecord, &mCompressionSession );
	if( err )
		goto bail;
	return;

bail:
	::ICMCompressionSessionOptionsRelease( sessionOptions );
	throw MovieWriterExc();
}

void MovieWriter::Obj::finish()
{
	mFinished = true; // set this in case of throw

	OSErr err;
	if( mMedia )  {
		err = ::EndMediaEdits( mMedia );
		if( err )
			throw MovieWriterExc();

		err = ::ExtendMediaDecodeDurationToDisplayEndTime( mMedia, NULL );
		if( err )
			throw MovieWriterExc();

		//Add media to track
		err = ::InsertMediaIntoTrack( mTrack, 0, 0, ::GetMediaDisplayDuration( mMedia ), fixed1 );
		if( err )
			throw MovieWriterExc();

		//Write movie
		err = ::AddMovieToStorage( mMovie, mDataHandler );
		if( err )
			throw MovieWriterExc();
	}

	//Close movie file
	if( mDataHandler )
		::CloseMovieStorage( mDataHandler );

	if( mMovie )
		::DisposeMovie( mMovie );
}

} } // namespace cinder::qtime<commit_msg>corevideo increment<commit_after>/*
 Copyright (c) 2010, The Barbarian Group
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this list of conditions and
 the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#if defined( CINDER_COCOA ) && ( ! defined( __OBJC__ ) )
#	error "This file must be compiled as Objective-C++ on the Mac"
#endif

#include "cinder/qtime/MovieWriter.h"
#include "cinder/qtime/QuickTimeUtils.h"

#if defined( CINDER_MAC )
	#include <QTKit/QTKit.h>
	#include "cinder/cocoa/CinderCocoa.h"
#else
	#pragma push_macro( "__STDC_CONSTANT_MACROS" )
		#undef __STDC_CONSTANT_MACROS
		#include <QTML.h>
		#include <CVPixelBuffer.h>
		#include <ImageCompression.h>
		#include <Movies.h>
		#include <CoreFoundation/CFBase.h>
		#include <CoreFoundation/CFNumber.h>
	#pragma pop_macro( "__STDC_CONSTANT_MACROS" )
#endif

namespace cinder { namespace qtime {

MovieWriter::MovieWriter( const std::string &outPath, int32_t width, int32_t height, MovieWriterCodecType codec, MovieWriterQuality quality )
	: mObj( shared_ptr<Obj>( new Obj( outPath, width, height, codec, quality ) ) )
{
}

MovieWriter::Obj::~Obj()
{
	if( ! mFinished )
		finish();
}

MovieWriter::Obj::Obj( const std::string &path, int32_t width, int32_t height, MovieWriterCodecType codec, MovieWriterQuality quality )
	: mPath( path ), mQuality( quality ), mWidth( width ), mHeight( height ), mFinished( false )
{
    OSErr       err = noErr;
    Handle      dataRef;
    OSType      dataRefType;

	startQuickTime();

    //Create movie file
	CFStringRef strDestMoviePath = ::CFStringCreateWithCString( kCFAllocatorDefault, path.c_str(), kCFStringEncodingUTF8 );
	err = ::QTNewDataReferenceFromFullPathCFString( strDestMoviePath, kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType );
	::CFRelease( strDestMoviePath );
	if( err )
        throw MovieWriterExcInvalidPath();

	// Create a movie for this file (data ref)
    err = ::CreateMovieStorage( dataRef, dataRefType, 'TVOD', smCurrentScript, createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &mDataHandler, &mMovie );
	::DisposeHandle( dataRef );
    if( err )
        throw MovieWriterExc();

	mTrack = ::NewMovieTrack( mMovie, width << 16, height << 16, 0 );
	err = ::GetMoviesError();
	if( err )
		throw MovieWriterExc();

	//Create track media
	::TimeScale timescale = 1000;
	mMedia = ::NewTrackMedia( mTrack, ::VideoMediaType, timescale, 0, 0 );
	err = GetMoviesError();
	if( err )
		throw MovieWriterExc();

	//Prepare media for editing
	err = ::BeginMediaEdits( mMedia );
mCodec = 'png ';
	createCompressionSession();
	mCurrentTimeValue = 0;
}

void MovieWriter::Obj::addFrame( const ImageSourceRef &imageSource )
{
	CVPixelBufferRef pixelBuffer = createCvPixelBuffer( imageSource );
	const float gamma = 2.5f;
	::CFNumberRef gammaLevel = CFNumberCreate( kCFAllocatorDefault, kCFNumberFloatType, &gamma );
	::CVBufferSetAttachment( pixelBuffer, kCVImageBufferGammaLevelKey, gammaLevel, kCVAttachmentMode_ShouldPropagate );

	ICMValidTimeFlags validTimeFlags = kICMValidTime_DisplayTimeStampIsValid | kICMValidTime_DisplayDurationIsValid;
	ICMCompressionFrameOptionsRef frameOptions = NULL;
	OSStatus err = ::ICMCompressionSessionEncodeFrame( mCompressionSession, pixelBuffer,
				mCurrentTimeValue, 60, validTimeFlags,
                frameOptions, NULL, NULL );
	mCurrentTimeValue += 60;
	if( err )
		MovieWriterExcFrameEncode();
}

extern "C" {
OSStatus MovieWriter::Obj::encodedFrameOutputCallback( void *refCon,
                   ICMCompressionSessionRef session,
                   OSStatus err,
                   ICMEncodedFrameRef encodedFrame,
                   void *reserved )
{
	MovieWriter::Obj *obj = reinterpret_cast<MovieWriter::Obj*>( refCon );
	OSStatus result = ::AddMediaSampleFromEncodedFrame( obj->mMedia, encodedFrame, NULL );
	return result;
}

}

void MovieWriter::Obj::createCompressionSession()
{
	OSStatus err = noErr;
	::ICMEncodedFrameOutputRecord encodedFrameOutputRecord = {0};
	::ICMCompressionSessionOptionsRef sessionOptions = NULL;

	err = ::ICMCompressionSessionOptionsCreate( NULL, &sessionOptions );
	if( err )
		goto bail;

	// We must set this flag to enable P or B frames.
	err = ::ICMCompressionSessionOptionsSetAllowTemporalCompression( sessionOptions, true );
	if( err )
		goto bail;

	// We must set this flag to enable B frames.
	err = ::ICMCompressionSessionOptionsSetAllowFrameReordering( sessionOptions, true );
	if( err )
		goto bail;

	// Set the maximum key frame interval, also known as the key frame rate.
	err = ::ICMCompressionSessionOptionsSetMaxKeyFrameInterval( sessionOptions, 30 );
	if( err )
		goto bail;

	// This allows the compressor more flexibility (ie, dropping and coalescing frames).
	err = ::ICMCompressionSessionOptionsSetAllowFrameTimeChanges( sessionOptions, true );
	if( err )
		goto bail;

	// We need durations when we store frames.
	err = ::ICMCompressionSessionOptionsSetDurationsNeeded( sessionOptions, true );
	if( err )
		goto bail;

	// Set the average data rate.
	/*err = ICMCompressionSessionOptionsSetProperty( sessionOptions,
				kQTPropertyClass_ICMCompressionSessionOptions,
				kICMCompressionSessionOptionsPropertyID_AverageDataRate,
				sizeof( averageDataRate ),
				&averageDataRate );*/
	if( err )
		goto bail;

	encodedFrameOutputRecord.encodedFrameOutputCallback = encodedFrameOutputCallback;
	encodedFrameOutputRecord.encodedFrameOutputRefCon = this;
	encodedFrameOutputRecord.frameDataAllocator = NULL;

	::TimeScale timeScale = 1000;
	err = ::ICMCompressionSessionCreate( NULL, mWidth, mHeight, mCodec, timeScale,
			sessionOptions, NULL, &encodedFrameOutputRecord, &mCompressionSession );
	if( err )
		goto bail;
	return;

bail:
	::ICMCompressionSessionOptionsRelease( sessionOptions );
	throw MovieWriterExc();
}

void MovieWriter::Obj::finish()
{
	mFinished = true; // set this in case of throw

	OSErr err;
	if( mMedia )  {
		err = ::EndMediaEdits( mMedia );
		if( err )
			throw MovieWriterExc();

		err = ::ExtendMediaDecodeDurationToDisplayEndTime( mMedia, NULL );
		if( err )
			throw MovieWriterExc();

		//Add media to track
		err = ::InsertMediaIntoTrack( mTrack, 0, 0, ::GetMediaDisplayDuration( mMedia ), fixed1 );
		if( err )
			throw MovieWriterExc();

		//Write movie
		err = ::AddMovieToStorage( mMovie, mDataHandler );
		if( err )
			throw MovieWriterExc();
	}

	//Close movie file
	if( mDataHandler )
		::CloseMovieStorage( mDataHandler );

	if( mMovie )
		::DisposeMovie( mMovie );
}

} } // namespace cinder::qtime<|endoftext|>


<commit_before><commit_msg>Delete ApeNodeImpl.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>:construction: chore(test): updated the demo for netpp<commit_after><|endoftext|>


<commit_before>/*=============================================================================
	Copyright (c) 2012-2014 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// definition for GibbsOpt constructor and destructor

#include "libgibbs/include/libgibbs_pch.hpp"
#include "libgibbs/include/models.hpp"
#include "libgibbs/include/utils/ast_container_rename.hpp"
#include "libgibbs/include/utils/math_expr.hpp"
#include "libgibbs/include/optimizer/opt_Gibbs.hpp"
#include "libgibbs/include/optimizer/utils/build_variable_map.hpp"
#include "libgibbs/include/optimizer/utils/ezd_minimization.hpp"
#include "libtdb/include/logging.hpp"
#include <sstream>

using namespace Optimizer;

// Add new_tree to root_tree
void add_trees ( boost::spirit::utree &root_tree, const boost::spirit::utree &new_tree )
    {
    boost::spirit::utree temp_tree;
    temp_tree.push_back ( "+" );
    temp_tree.push_back ( root_tree );
    temp_tree.push_back ( new_tree );
    root_tree.swap ( temp_tree );
    }

GibbsOpt::GibbsOpt (
    const Database &DB,
    const evalconditions &sysstate ) :
    conditions ( sysstate )
    {
    BOOST_LOG_NAMED_SCOPE ( "GibbsOpt::GibbsOpt" );
    BOOST_LOG_CHANNEL_SEV ( opto_log, "optimizer", debug ) << "enter ctor";
    auto varcount = 0;
    auto activephases = 0;
    parameter_set pset;
    Phase_Collection phase_col;

    for ( auto i = DB.get_phase_iterator(); i != DB.get_phase_iterator_end(); ++i )
        {
        if ( conditions.phases.find ( i->first ) != conditions.phases.end() )
            {
            if ( conditions.phases.at ( i->first ) == PhaseStatus::ENTERED )
                {
                phase_col[i->first] = i->second;
                }
            }
        }

    if ( conditions.elements.cbegin() == conditions.elements.cend() ) BOOST_LOG_SEV ( opto_log, critical ) << "No components entered!";
    if ( phase_col.begin() == phase_col.end() ) BOOST_LOG_SEV ( opto_log, critical ) << "No phases found!";

    // build_variable_map() will fill main_indices by reference
    // main_indices is used during the optimization as a simplified variable map
    main_ss = build_variable_map ( phase_col.begin(), phase_col.end(), conditions, main_indices );

    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        BOOST_LOG_SEV ( opto_log, debug ) << "Variable " << i->second << ": " << i->first;
        }

    // load the parameters from the database
    pset = DB.get_parameter_set();

    // this is the part where we look up the models enabled for each phase and call their AST builders
    // then we build a master Gibbs AST for the objective function
    auto temp_phase_col = phase_col; // We modify phase_col, so we should be careful here
    for ( auto i = temp_phase_col.begin(); i != temp_phase_col.end(); ++i )
        {
        ++activephases;
        CompositionSet main_compset = CompositionSet ( i->second, pset, main_ss, main_indices );
        std::vector<std::map<std::string,double>> minima = Optimizer::LocateMinima ( main_compset, main_ss, conditions );
        BOOST_LOG_SEV ( opto_log, debug ) << minima.size() << " minima detected from global minimization";

        if ( minima.size() == 1 )
            {
            // No miscibility gap, no need to create new composition sets
            // Use the minimum found during global minimization as the starting point
            main_compset.set_starting_point ( * ( minima.begin() ) );
            const std::string compset_name ( main_compset.name() );
            comp_sets.emplace ( compset_name, std::move ( main_compset ) );
            }
        if ( minima.size() > 1 )
            {
            // Miscibility gap detected; create a new composition set for each minimum
            std::size_t compsetcount = 1;
            std::map<std::string, CompositionSet>::iterator it;
            for ( auto min = minima.begin(); min != minima.end(); ++min )
                {
                if ( min != minima.begin() )
                    {
                        ++compsetcount;
                        ++activephases;
                    }
                std::stringstream compsetname;
                compsetname << main_compset.name() << "#" << compsetcount;

                // Set starting point
                const auto new_starting_point = ast_copy_with_renamed_phase(*min, main_compset.name(), compsetname.str());
                // Copy from PHASENAME to PHASENAME#N
                phase_col[compsetname.str()] = phase_col[main_compset.name()];
                conditions.phases[compsetname.str()] = conditions.phases[main_compset.name()];
                it = comp_sets.emplace ( compsetname.str(), CompositionSet( main_compset, new_starting_point, compsetname.str() ) ).first;
                }
            }
            // Remove PHASENAME
            // PHASENAME was renamed to PHASENAME#1
            BOOST_LOG_SEV ( opto_log, debug ) << "Removing old phase " << main_compset.name();
            auto remove_phase_iter = phase_col.find ( main_compset.name() );
            auto remove_conds_phase_iter = conditions.phases.find ( main_compset.name() );
            if ( remove_phase_iter != phase_col.end() ) phase_col.erase ( remove_phase_iter );
            if ( remove_conds_phase_iter != conditions.phases.end() ) {
                conditions.phases.erase ( remove_conds_phase_iter );
            }
            // Rebuild the index map now that phases have been renamed and removed
            BOOST_LOG_SEV ( opto_log, debug ) << "Rebuilding variable map";
            main_indices.left.clear();
            main_ss = build_variable_map ( phase_col.begin(), phase_col.end(), conditions, main_indices );
        }

    // Add the mandatory constraints to the ConstraintManager
    if ( activephases > 1 )
        cm.addConstraint (
            PhaseFractionBalanceConstraint (
                phase_col.begin(), phase_col.end()
            )
        ); // Add the mass balance constraint to ConstraintManager (mandatory)
    if ( activephases == 1 )
        {
        // If only one phase is present, fix its corresponding variable index
        std::stringstream ss;
        ss << ( phase_col.begin() )->first << "_FRAC";
        fixed_indices.push_back ( main_indices.left.at ( ss.str() ) );
        }

    // Add the sublattice site fraction constraints (mandatory)
    for ( auto i = phase_col.begin(); i != phase_col.end(); ++i )
        {
        for ( auto j = i->second.get_sublattice_iterator(); j != i->second.get_sublattice_iterator_end(); ++j )
            {
            std::vector<std::string> subl_list;
            for ( auto k = ( *j ).get_species_iterator(); k != ( *j ).get_species_iterator_end(); ++k )
                {
                // Check if this species in this sublattice is on our list of elements to investigate
                if ( std::find ( conditions.elements.cbegin(),conditions.elements.cend(),*k ) != conditions.elements.cend() )
                    {
                    subl_list.push_back ( *k ); // Add to the list
                    }
                }
            if ( subl_list.size() == 1 )
                {
                std::stringstream ss;
                ss << i->first << "_" << std::distance ( i->second.get_sublattice_iterator(),j ) << "_" << * ( subl_list.begin() );
                fixed_indices.push_back ( main_indices.left.at ( ss.str() ) );
                }
            if ( subl_list.size() > 1 )
                {
                cm.addConstraint (
                    SublatticeBalanceConstraint (
                        i->first,
                        std::distance ( i->second.get_sublattice_iterator(),j ),
                        subl_list.cbegin(),
                        subl_list.cend()
                    )
                );
                }
            }
        }

    // Add any user-specified constraints to the ConstraintManager

    for ( auto i = conditions.xfrac.cbegin(); i != conditions.xfrac.cend(); ++i )
        {
        cm.addConstraint ( MassBalanceConstraint ( phase_col.begin(), phase_col.end(), i->first, i->second ) );
        }

    for ( auto i = cm.constraints.begin() ; i != cm.constraints.end(); ++i )
        {
        BOOST_LOG_SEV ( opto_log, debug ) << "Constraint " << i->name << " LHS: " << i->lhs;
        BOOST_LOG_SEV ( opto_log, debug ) << "Constraint " << i->name << " RHS: " << i->rhs;
        }

    // Calculate first derivative ASTs of all constraints
    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        // for each variable, calculate derivatives of all the constraints
        for ( auto j = cm.constraints.begin(); j != cm.constraints.end(); ++j )
            {
            boost::spirit::utree lhs = differentiate_utree ( j->lhs, i->first );
            boost::spirit::utree rhs = differentiate_utree ( j->rhs, i->first );
            lhs = simplify_utree ( lhs );
            rhs = simplify_utree ( rhs );
            if (
                ( lhs.which() == boost::spirit::utree_type::double_type || lhs.which() == boost::spirit::utree_type::int_type )
                &&
                ( rhs.which() == boost::spirit::utree_type::double_type || rhs.which() == boost::spirit::utree_type::int_type )
            )
                {
                double lhsget, rhsget;
                lhsget = lhs.get<double>();
                rhsget = rhs.get<double>();
                if ( lhsget == rhsget ) continue; // don't add zeros to the Jacobian
                }
            boost::spirit::utree subtract_tree;
            subtract_tree.push_back ( "-" );
            subtract_tree.push_back ( lhs );
            subtract_tree.push_back ( rhs );
            int var_index = i->second;
            int cons_index = std::distance ( cm.constraints.begin(),j );
            jac_g_trees.push_back ( jacobian_entry ( cons_index,var_index,false,subtract_tree ) );
            BOOST_LOG_SEV ( opto_log, debug ) << "Jacobian of constraint  " << cons_index << " wrt variable " << var_index << " pre-calculated";
            }
        }

    // Add nonzero elements from objective Hessian to sparsity structure
    for ( auto i = comp_sets.cbegin(); i != comp_sets.cend(); ++i )
        {
        std::set<std::list<int>> comp_set_hess_sparsity_structure = i->second.hessian_sparsity_structure ( main_indices );
        for ( auto j = comp_set_hess_sparsity_structure.cbegin(); j != comp_set_hess_sparsity_structure.cend(); ++j )
            {
            hess_sparsity_structure.insert ( *j );
            }
        }

    // Calculate second derivatives of constraints
    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        // for each variable, calculate derivatives of the Jacobian w.r.t all the constraints
        for ( auto j = jac_g_trees.cbegin(); j != jac_g_trees.cend(); ++j )
            {
            if ( i->second > j->var_index ) continue; // skip upper triangular
            // second derivative of constraint jac_g_trees->cons_index w.r.t jac_g_trees->var_index, i->second
            boost::spirit::utree cons_second_deriv = differentiate_utree ( j->ast, i->first );
            //cons_second_deriv = simplify_utree(cons_second_deriv);
            hessian_set::iterator h_iter, h_end;
            // don't add zeros to the Hessian
            if ( is_zero_tree ( cons_second_deriv ) ) continue;

            h_iter = constraint_hessian_data.lower_bound ( boost::make_tuple ( i->second,j->var_index ) );
            h_end = constraint_hessian_data.upper_bound ( boost::make_tuple ( i->second,j->var_index ) );
            // create a new Hessian record if it does not exist
            if ( h_iter == h_end ) h_iter = constraint_hessian_data.insert ( hessian_entry ( i->second,j->var_index ) ).first;
            hessian_entry h_entry = *h_iter;
            h_entry.asts[j->cons_index] = cons_second_deriv; // set AST for constraint Hessian
            constraint_hessian_data.replace ( h_iter, h_entry ); // update original entry
            const std::list<int> nonzerolist {i->second, j->var_index};
            hess_sparsity_structure.insert ( nonzerolist ); // add nonzero to sparsity structure
            BOOST_LOG_SEV ( opto_log, debug ) << "Hessian of constraint  "
                                              << j->cons_index << " (" << i->second << "," << j->var_index << ") pre-calculated";
            }
        }

    BOOST_LOG_SEV ( opto_log, debug ) << "function exit";
    }

GibbsOpt::~GibbsOpt()
    {}
// kate: indent-mode cstyle; indent-width 4; replace-tabs on;
<commit_msg>Add assert for global minimization result<commit_after>/*=============================================================================
	Copyright (c) 2012-2014 Richard Otis

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// definition for GibbsOpt constructor and destructor

#include "libgibbs/include/libgibbs_pch.hpp"
#include "libgibbs/include/models.hpp"
#include "libgibbs/include/utils/ast_container_rename.hpp"
#include "libgibbs/include/utils/math_expr.hpp"
#include "libgibbs/include/optimizer/opt_Gibbs.hpp"
#include "libgibbs/include/optimizer/utils/build_variable_map.hpp"
#include "libgibbs/include/optimizer/utils/ezd_minimization.hpp"
#include "libtdb/include/logging.hpp"
#include <sstream>

using namespace Optimizer;

// Add new_tree to root_tree
void add_trees ( boost::spirit::utree &root_tree, const boost::spirit::utree &new_tree )
    {
    boost::spirit::utree temp_tree;
    temp_tree.push_back ( "+" );
    temp_tree.push_back ( root_tree );
    temp_tree.push_back ( new_tree );
    root_tree.swap ( temp_tree );
    }

GibbsOpt::GibbsOpt (
    const Database &DB,
    const evalconditions &sysstate ) :
    conditions ( sysstate )
    {
    BOOST_LOG_NAMED_SCOPE ( "GibbsOpt::GibbsOpt" );
    BOOST_LOG_CHANNEL_SEV ( opto_log, "optimizer", debug ) << "enter ctor";
    auto varcount = 0;
    auto activephases = 0;
    parameter_set pset;
    Phase_Collection phase_col;

    for ( auto i = DB.get_phase_iterator(); i != DB.get_phase_iterator_end(); ++i )
        {
        if ( conditions.phases.find ( i->first ) != conditions.phases.end() )
            {
            if ( conditions.phases.at ( i->first ) == PhaseStatus::ENTERED )
                {
                phase_col[i->first] = i->second;
                }
            }
        }

    if ( conditions.elements.cbegin() == conditions.elements.cend() ) BOOST_LOG_SEV ( opto_log, critical ) << "No components entered!";
    if ( phase_col.begin() == phase_col.end() ) BOOST_LOG_SEV ( opto_log, critical ) << "No phases found!";

    // build_variable_map() will fill main_indices by reference
    // main_indices is used during the optimization as a simplified variable map
    main_ss = build_variable_map ( phase_col.begin(), phase_col.end(), conditions, main_indices );

    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        BOOST_LOG_SEV ( opto_log, debug ) << "Variable " << i->second << ": " << i->first;
        }

    // load the parameters from the database
    pset = DB.get_parameter_set();

    // this is the part where we look up the models enabled for each phase and call their AST builders
    // then we build a master Gibbs AST for the objective function
    auto temp_phase_col = phase_col; // We modify phase_col, so we should be careful here
    for ( auto i = temp_phase_col.begin(); i != temp_phase_col.end(); ++i )
        {
        ++activephases;
        CompositionSet main_compset = CompositionSet ( i->second, pset, main_ss, main_indices );
        std::vector<std::map<std::string,double>> minima = Optimizer::LocateMinima ( main_compset, main_ss, conditions );
        BOOST_LOG_SEV ( opto_log, debug ) << minima.size() << " minima detected from global minimization";

        BOOST_ASSERT ( minima.size() > 0);

        if ( minima.size() == 1 )
            {
            // No miscibility gap, no need to create new composition sets
            // Use the minimum found during global minimization as the starting point
            main_compset.set_starting_point ( * ( minima.begin() ) );
            const std::string compset_name ( main_compset.name() );
            comp_sets.emplace ( compset_name, std::move ( main_compset ) );
            }
        if ( minima.size() > 1 )
            {
            // Miscibility gap detected; create a new composition set for each minimum
            std::size_t compsetcount = 1;
            std::map<std::string, CompositionSet>::iterator it;
            for ( auto min = minima.begin(); min != minima.end(); ++min )
                {
                if ( min != minima.begin() )
                    {
                        ++compsetcount;
                        ++activephases;
                    }
                std::stringstream compsetname;
                compsetname << main_compset.name() << "#" << compsetcount;

                // Set starting point
                const auto new_starting_point = ast_copy_with_renamed_phase(*min, main_compset.name(), compsetname.str());
                // Copy from PHASENAME to PHASENAME#N
                phase_col[compsetname.str()] = phase_col[main_compset.name()];
                conditions.phases[compsetname.str()] = conditions.phases[main_compset.name()];
                it = comp_sets.emplace ( compsetname.str(), CompositionSet( main_compset, new_starting_point, compsetname.str() ) ).first;
                }
            }
            // Remove PHASENAME
            // PHASENAME was renamed to PHASENAME#1
            BOOST_LOG_SEV ( opto_log, debug ) << "Removing old phase " << main_compset.name();
            auto remove_phase_iter = phase_col.find ( main_compset.name() );
            auto remove_conds_phase_iter = conditions.phases.find ( main_compset.name() );
            if ( remove_phase_iter != phase_col.end() ) phase_col.erase ( remove_phase_iter );
            if ( remove_conds_phase_iter != conditions.phases.end() ) {
                conditions.phases.erase ( remove_conds_phase_iter );
            }
            // Rebuild the index map now that phases have been renamed and removed
            BOOST_LOG_SEV ( opto_log, debug ) << "Rebuilding variable map";
            main_indices.left.clear();
            main_ss = build_variable_map ( phase_col.begin(), phase_col.end(), conditions, main_indices );
        }

    // Add the mandatory constraints to the ConstraintManager
    if ( activephases > 1 )
        cm.addConstraint (
            PhaseFractionBalanceConstraint (
                phase_col.begin(), phase_col.end()
            )
        ); // Add the mass balance constraint to ConstraintManager (mandatory)
    if ( activephases == 1 )
        {
        // If only one phase is present, fix its corresponding variable index
        std::stringstream ss;
        ss << ( phase_col.begin() )->first << "_FRAC";
        fixed_indices.push_back ( main_indices.left.at ( ss.str() ) );
        }

    // Add the sublattice site fraction constraints (mandatory)
    for ( auto i = phase_col.begin(); i != phase_col.end(); ++i )
        {
        for ( auto j = i->second.get_sublattice_iterator(); j != i->second.get_sublattice_iterator_end(); ++j )
            {
            std::vector<std::string> subl_list;
            for ( auto k = ( *j ).get_species_iterator(); k != ( *j ).get_species_iterator_end(); ++k )
                {
                // Check if this species in this sublattice is on our list of elements to investigate
                if ( std::find ( conditions.elements.cbegin(),conditions.elements.cend(),*k ) != conditions.elements.cend() )
                    {
                    subl_list.push_back ( *k ); // Add to the list
                    }
                }
            if ( subl_list.size() == 1 )
                {
                std::stringstream ss;
                ss << i->first << "_" << std::distance ( i->second.get_sublattice_iterator(),j ) << "_" << * ( subl_list.begin() );
                fixed_indices.push_back ( main_indices.left.at ( ss.str() ) );
                }
            if ( subl_list.size() > 1 )
                {
                cm.addConstraint (
                    SublatticeBalanceConstraint (
                        i->first,
                        std::distance ( i->second.get_sublattice_iterator(),j ),
                        subl_list.cbegin(),
                        subl_list.cend()
                    )
                );
                }
            }
        }

    // Add any user-specified constraints to the ConstraintManager

    for ( auto i = conditions.xfrac.cbegin(); i != conditions.xfrac.cend(); ++i )
        {
        cm.addConstraint ( MassBalanceConstraint ( phase_col.begin(), phase_col.end(), i->first, i->second ) );
        }

    for ( auto i = cm.constraints.begin() ; i != cm.constraints.end(); ++i )
        {
        BOOST_LOG_SEV ( opto_log, debug ) << "Constraint " << i->name << " LHS: " << i->lhs;
        BOOST_LOG_SEV ( opto_log, debug ) << "Constraint " << i->name << " RHS: " << i->rhs;
        }

    // Calculate first derivative ASTs of all constraints
    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        // for each variable, calculate derivatives of all the constraints
        for ( auto j = cm.constraints.begin(); j != cm.constraints.end(); ++j )
            {
            boost::spirit::utree lhs = differentiate_utree ( j->lhs, i->first );
            boost::spirit::utree rhs = differentiate_utree ( j->rhs, i->first );
            lhs = simplify_utree ( lhs );
            rhs = simplify_utree ( rhs );
            if (
                ( lhs.which() == boost::spirit::utree_type::double_type || lhs.which() == boost::spirit::utree_type::int_type )
                &&
                ( rhs.which() == boost::spirit::utree_type::double_type || rhs.which() == boost::spirit::utree_type::int_type )
            )
                {
                double lhsget, rhsget;
                lhsget = lhs.get<double>();
                rhsget = rhs.get<double>();
                if ( lhsget == rhsget ) continue; // don't add zeros to the Jacobian
                }
            boost::spirit::utree subtract_tree;
            subtract_tree.push_back ( "-" );
            subtract_tree.push_back ( lhs );
            subtract_tree.push_back ( rhs );
            int var_index = i->second;
            int cons_index = std::distance ( cm.constraints.begin(),j );
            jac_g_trees.push_back ( jacobian_entry ( cons_index,var_index,false,subtract_tree ) );
            BOOST_LOG_SEV ( opto_log, debug ) << "Jacobian of constraint  " << cons_index << " wrt variable " << var_index << " pre-calculated";
            }
        }

    // Add nonzero elements from objective Hessian to sparsity structure
    for ( auto i = comp_sets.cbegin(); i != comp_sets.cend(); ++i )
        {
        std::set<std::list<int>> comp_set_hess_sparsity_structure = i->second.hessian_sparsity_structure ( main_indices );
        for ( auto j = comp_set_hess_sparsity_structure.cbegin(); j != comp_set_hess_sparsity_structure.cend(); ++j )
            {
            hess_sparsity_structure.insert ( *j );
            }
        }

    // Calculate second derivatives of constraints
    for ( auto i = main_indices.left.begin(); i != main_indices.left.end(); ++i )
        {
        // for each variable, calculate derivatives of the Jacobian w.r.t all the constraints
        for ( auto j = jac_g_trees.cbegin(); j != jac_g_trees.cend(); ++j )
            {
            if ( i->second > j->var_index ) continue; // skip upper triangular
            // second derivative of constraint jac_g_trees->cons_index w.r.t jac_g_trees->var_index, i->second
            boost::spirit::utree cons_second_deriv = differentiate_utree ( j->ast, i->first );
            //cons_second_deriv = simplify_utree(cons_second_deriv);
            hessian_set::iterator h_iter, h_end;
            // don't add zeros to the Hessian
            if ( is_zero_tree ( cons_second_deriv ) ) continue;

            h_iter = constraint_hessian_data.lower_bound ( boost::make_tuple ( i->second,j->var_index ) );
            h_end = constraint_hessian_data.upper_bound ( boost::make_tuple ( i->second,j->var_index ) );
            // create a new Hessian record if it does not exist
            if ( h_iter == h_end ) h_iter = constraint_hessian_data.insert ( hessian_entry ( i->second,j->var_index ) ).first;
            hessian_entry h_entry = *h_iter;
            h_entry.asts[j->cons_index] = cons_second_deriv; // set AST for constraint Hessian
            constraint_hessian_data.replace ( h_iter, h_entry ); // update original entry
            const std::list<int> nonzerolist {i->second, j->var_index};
            hess_sparsity_structure.insert ( nonzerolist ); // add nonzero to sparsity structure
            BOOST_LOG_SEV ( opto_log, debug ) << "Hessian of constraint  "
                                              << j->cons_index << " (" << i->second << "," << j->var_index << ") pre-calculated";
            }
        }

    BOOST_LOG_SEV ( opto_log, debug ) << "function exit";
    }

GibbsOpt::~GibbsOpt()
    {}
// kate: indent-mode cstyle; indent-width 4; replace-tabs on;
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007,2008   Alex Shulgin
 *
 * This file is part of png++ the C++ wrapper for libpng.  PNG++ is free
 * software; the exact copying conditions are as follows:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef PNGPP_ERROR_HPP_INCLUDED
#define PNGPP_ERROR_HPP_INCLUDED

#include <stdexcept>
#include <cerrno>
#include <cstdlib>

namespace png
{

    /**
     * \brief Exception class to represent runtime errors related to
     * png++ operation.
     */
    class error
        : public std::runtime_error
    {
    public:
        /**
         * \param  message  error description
         */
        explicit error(std::string const& message)
            : std::runtime_error(message)
        {
        }
    };

    /**
     * \brief Exception class to represent standard library errors
     * (generally IO).
     *
     * \see  reader, writer
     */
    class std_error
        : public std::runtime_error
    {
    public:
        /**
         * Constructs an std_error object.  The \a message string is
         * appended with <tt>": "</tt> and the error description as
         * returned by \c strerror(\a error).
         *
         * \param  message  error description
         * \param  error    error number
         */
        explicit std_error(std::string const& message, int error = errno)
            : std::runtime_error((message + ": ") + strerror(error))
        {
        }
    };

} // namespace png

#endif // PNGPP_ERROR_HPP_INCLUDED
<commit_msg>Added #include <string> for error.hpp: fix compilation on Win32.<commit_after>/*
 * Copyright (C) 2007,2008   Alex Shulgin
 *
 * This file is part of png++ the C++ wrapper for libpng.  PNG++ is free
 * software; the exact copying conditions are as follows:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef PNGPP_ERROR_HPP_INCLUDED
#define PNGPP_ERROR_HPP_INCLUDED

#include <string>
#include <stdexcept>
#include <cerrno>
#include <cstdlib>

namespace png
{

    /**
     * \brief Exception class to represent runtime errors related to
     * png++ operation.
     */
    class error
        : public std::runtime_error
    {
    public:
        /**
         * \param  message  error description
         */
        explicit error(std::string const& message)
            : std::runtime_error(message)
        {
        }
    };

    /**
     * \brief Exception class to represent standard library errors
     * (generally IO).
     *
     * \see  reader, writer
     */
    class std_error
        : public std::runtime_error
    {
    public:
        /**
         * Constructs an std_error object.  The \a message string is
         * appended with <tt>": "</tt> and the error description as
         * returned by \c strerror(\a error).
         *
         * \param  message  error description
         * \param  error    error number
         */
        explicit std_error(std::string const& message, int error = errno)
            : std::runtime_error((message + ": ") + strerror(error))
        {
        }
    };

} // namespace png

#endif // PNGPP_ERROR_HPP_INCLUDED
<|endoftext|>


<commit_before><commit_msg>- Better help<commit_after><|endoftext|>