Введение
Сегодняни один из современных фильмов, выходящих на экран, ни одна компьютерная игра,не обходится без визуальных эффектов. Для того чтобы привлечь вниманиетребовательного потребителя создаются сногсшибательные трюки и невероятныеэффекты.
Обычнонад созданием визуальных эффектов работает целый штат профессионалов в областикомпьютерной графики и видеомонтажа. Использование при редактированиивидеоматериала передовых технологий позволяет добавлять в финальную картинкуновые объекты, «вырезать» неудачно попавшую в кадр деталь и многодругое.
Споявлением трехмерной компьютерной графики стало возможным использоватьпрактически любую декорацию. Но, несмотря на то, что спецэффекты, которые можнонаблюдать в современных фильмах, кажутся очень сложными, на создание многих изних уходит намного меньше времени, чем может подумать неподготовленный зритель.
Безусловно,использование трехмерной анимации — это гарантия того, что обработанныйвидеоматериал или игровая сцена, просчитывающаяся в реальном времени, будетвыглядеть захватывающе. Однако, для того чтобы получить сложный компьютерныйэффект, требуется очень много ресурсов. К тому же, просчет сложных трехмерныхсцен может занять немало времени. Существует множество приемов, используякоторые можно получить те же спецэффекты с гораздо меньшими затратами, каквремени, так и сил.
Многиеэффекты в трехмерной графике создаются при помощи частиц. Это и брызги воды, иискры бенгальского огня, и разлетающиеся обломки взорвавшегося автомобиля. Припомощи систем частиц одновременно создается большое количество одинаковыхобъектов, поведением которых можно легко управлять. Для создания,редактирования и интеграции в конечное приложение эффектов частиц используютсяспециальные программы – редакторы частиц. В отличие от профессиональных пакетовдля работы с 3D, они обычно содержат заранеепросчитанные алгоритмы поведения частиц. Этим объясняется их быстродействие(обычно такие программы работают в режиме реального времени).
Разработанноев рамках данной работы программное средство “Easy Particles” является несложным вариантомредактора частиц, позволяющее оперировать рядом физических сил припрограммировании эффектов частиц. К основным его достоинствам можно отнести:
— данноепрограммное средство является полностью бесплатным, на него не нужно покупатькоммерческую лицензию;
— в отличиеот профессиональных пакетов работы с частицами, научиться работать с даннымредактором можно буквально за несколько минут;
— при этомдоступно создание сложных, многоступенчатых эффектов, с использованиеминтуитивно-понятной многоступенчатой схемы;
— использование графического конвейера OpenGL позволило максимально ускорить процесс расчётов, так что вывод графики врежиме реального времени возможен при очень больших количествах полигонов;
— низкиетребования, стабильность и простота настройки и работы;
— удобныйграфический пользовательский интерфейс;
В даннойпояснительной записке представлено подробное описание разработанного редакторачастиц.
Отчёт состоитиз шести разделов.
В разделе “Постановказадачи” описывается предметная область с выделением ключевых абстракций,формулируются требование к задаче, обосновывается выбор инструментов реализациизадачи и содержится краткий обзор существующих программ аналогичного характера.
В разделе “Проектированиеи реализация задачи” приводится список классов с их описанием, рассматриваетсяфизическая и логическая организация данных, дается описание концептуальногопрототипа, а также приводятся функции и элементы управления, которыми оперируетпрограмма.
В разделе “Тестирование”проводится анализ надёжности программы, примеры тестовых результатов, реакцияпрограммы на исключительные ситуации, анализ полученных результатов.
В разделе “Применениепрограммы” приводится назначение программы с областью применения, описываетсяаппаратно-программный комплекс для нормального функционирования программы,система помощи, разбирается инсталляция программы, диалог с пользователем.
Вразделах “Оптимизация зрительного взаимодействия оператора со средствамиотображения информации па основе ЭЛТ”, “Обоснование экономическойцелесообразности разработки ПС “EasyParticles” ” представленысведения, заданные для каждого раздела соответственно.
1. Постановка задачи
1.1 Требования кразрабатываемому программному средству
Разрабатываемоепрограммное средство должно осуществлять следующие основные функции:
— управление динамическим набором эмиттеров (систем частиц);
— управление частицами каждого эмиттера;
— управление общими параметрами рисования;
— ввод и вывод данных на внешние носители;
— вывод справочных данных о разработчике, способах использования программногосредства;
Программноесредство должно обеспечивать оперирование как можно более полным наборомхарактеристик эмиттеров, в то же время без перегрузки излишними второстепеннымипараметрами. При этом, параметры не должны вступать в противоречие друг сдругом (например, дублирование существенной части функциональности одногопараметра – другим). Интерфейс должен быть продуманным, без лишних элементов.Он должен соответствовать принципу: создание простого эффекта – легко, асложного – возможно. Основные два принципа реализации – простота ифункциональность.
Входнымиданными приложения являются параметры эмиттеров, задаваемые пользователем,параметры режима рисования.
Выходными даннымиявляются отображаемые в окне вывода редактора, либо в заданном окне заданногоприложения, графические объекты (частицы), трансформирующиеся под воздействиемзаданных сил, также выводимые в файл данные.
1.2 Обоснованиеактуальности темы ДП
Темойдипломного проекта была выбрано автоматизированное редактирование частиц вкомпьютерной графике. Выбор был сделан в соответствии с анализом тенденцийсложившихся в последнее время в мире компьютерной графики, а также по наличиюнекоторых личных профессиональных стремлений.
В последнее время созданиесложных графических анимационных эффектов с использованием специализированныхпакетов программных средств получило широчайшее распространение, как ворганизациях, так и среди обычных пользователей домашних компьютеров. При этом,на фоне большого числа сложных и дорогих коммерческих решений практическиотсутствуют более общие и простые бесплатные варианты редакторов,предназначенных для начинающих. Целью разработки было несколько восполнить этотпробел. Ведь часто дизайнеру графического приложения, будь то игра, или что быто ни было ещё, требуется быстро создать относительно несложный эффект (или егонабросок) и сразу же перейти к выполнению других, более приоритетных на данныймомент задач. Вместо этого, он зачастую вынужден тратить много времени наизучение документации сложных программных продуктов, создавать в рамках своегообучения тестовые примеры, и т.п. Благодаря данному программному средству,однако, задача быстрого создания эффектов частиц вполне реализуема не толькодля профессионального дизайнера компьютерной графики, но и для обычноголюбителя, осуществляющего своё первое знакомство с подобными приложениями.
1.3 Обзор существующихрешений
Насегодняшний день существует множество приложений для работы с системами частиц.Вот некоторые наиболее популярные из них:
a)ParticleIllusion;
б)Trapcode Particular;
в)Magic Particles;
Продукткомпании Wondertouch[10] ParticleIllusionна сегодняшний день является, пожалуй, наиболее всеохватывающим средствомсоздания эффектов частиц. Изначально включает довольно большую библиотекубесплатных эффектов, обновляемую каждый месяц. Обладает высокой расширяемостью(подключение дополнительных эмиттеров, к примеру).
TrapcodeParticular – встраиваемый (необязательный) модуль для пакета программ AdobeAfter Effects,предназначенный для редактирования частиц, разработанный компанией Trapcode [11].Немного менее широкий по возможностям, нежели ParticleIllusion,к тому же требующий для работы предустановленного Adobe After Effects.
MagicParticles – российский генератор частиц компании Астралакс [12]. Позволяет быстрои наглядно создавать визуальные спецэффекты на основе систем частиц. Основноедостоинство Magic Particles – мгновенное отображение всех изменений бездлительного процесса визуализации. Хотя то же можно сказать и о ParticleIllusion.Аналогично, в состав Magic Particles входит около сотни готовых образцов,которые можно использовать как есть или изменять по своим потребностям. Хотя помногим аспектам функциональности данный продукт уступает ParticleIllusion,к нему постоянно выходят обновления с исправлениями и дополнениями.
Все, за исключениемпоследнего, перечисленные редакторы частиц распространяются платно.
1.4 Цели и задачипроекта
Основнойзадачей является разработка редактора частиц, позволяющего, в отличие от вышеперечисленныхпрограммных продуктов, не тратя большого времени на чтение документации,создавать несложные эффекты. Это должно позволить привлечь большое числопользователей непрофессионалов к использованию приложения, в том числе в целяхознакомления с основными приёмами по созданию эффектов частиц.
Длябольшей открытости и возможности ручного редактирования выходные файлыредактора должны иметь формат XML.В данной (начальной) версии редактора допускается также хранение в том жевыходном файле иных, дополнительных параметров проекта. В будущих версиях,возможно, будет осуществлён переход на многофайловую систему хранения данныхпроекта, для обеспечения большей ясности при их ручной обработке.
Выводрезультирующей графической информации должен осуществляться в окно редактора. Однакопри этом должна быть реализована возможность подключения и использованиявыходных данных редактора (созданных эффектов) к внешним графическимприложениям.
Другойважной задачей является разработка приложения с возможностями последующегорасширения. Нужно отметить, что разрабатываемое в рамках дипломногопроектирования программное средство является прототипом, реализующим лишьосновные функциональные возможности программ данного класса. Поэтому необходимопозаботиться о будущих модификациях основной функциональности, возможностяхлёгкого добавления новых параметров, а также поддержке многоплатформенности(поддержка MacOS X).При этом очень важным остаётся вопрос разработки такого пользовательскогографического интерфейса, чтобы в него можно было легко и без ущерба дляудобства работы дизайнера интегрировать новые элементы, связанные с описаннымивыше новыми возможностями. Это очень важная задача, поэтому именно проработкеграфического пользовательского интерфейса следует уделить максимум времени приразработке программного средства. Более подробно о будущих планируемыхрасширениях редактора будет сказано ниже.
Таким образом, цельюработы является разработка доступного, легко расширяемого и простого в использованииредактора частиц.
1.5 Описаниепрограммно-алгоритмического обеспечения решения поставленной задачи
1.5.1 Среда дляпроектирования и разработки программных продуктов MicrosoftVisual Studio2005
MicrosoftVisual Studio — линейка продуктов компании Microsoft,включающих интегрированную среду разработки программного обеспечения и ряддругих инструментальных средств. В их число входят редакторы и компиляторыязыков VisualBasic.NET,Visual C++,Visual C#и некоторые другие. Также, что весьма важно, VisualStudio предлагает подробнуюинформацию о библиотеках и языках, включённых в пакет, в MSDN– информационной библиотеке по продуктам Microsoft,с возможностью получения недостающей информации из Интернета. Любойпрограммист, создающий приложения для Windows,весьма быстро убеждается в абсолютной необходимости данного средства приразработке. Также нужно отметить, что MicrosoftVisualStudio построена в архитектуре, поддерживающей возможность использованиядополнений от сторонних разработчиков, что позволяет расширять возможностисреды разработки. Более подробную информацию о данном пакете можно получить наофициальном сайте производителя [13] и в Интернете.
Средаразработки MSVisual Studio2005 была выбрана мною, так как создаваемое программное средство ориентированодля использования в ОС Windows.В ходе кодирования приложения, его тестирования и отладки и даже проектированиябыли использованы различные компоненты среды: компилятор C++,сборщик объектных C++ файлов,отладчик, средства обратного проектирования, позволяющие создавать диаграммыклассов для проекта по исходному коду его компилируемых единиц, на основе средстваMS Visio2003.
1.5.2 Языкпрограммирования C++
C++— компилируемый строго типизированный язык программирования общего назначения. Поддерживаетразные парадигмы программирования: процедурную, обобщённую, функциональную;наибольшее внимание уделено поддержке объектно-ориентированногопрограммирования. В 1990-х годах язык стал одним из наиболее широко применяемыхязыков программирования общего назначения. Более полную информацию можнополучить, например, прочитав книгу создателя языка Бьёрна Страуструпа [1].
ЯзыкС++ был выбран мною по причине его высочайшей гибкости и, конечно же, высокойпроработанности парадигмы объектно-ориентированного программирования. Сприменением именно этой парадигмы осуществлена реализация приложения.Приложение полностью построено на объектах C++классов (в качестве исключения имеется несколько используемых C-функций),при этом широко используются концепции наследования, инкапсуляции иполиморфизма, mutable-члены данных,шаблонные классы и функции. Достаточно широко применяются шаблоны контейнеровиз стандартной библиотеки шаблонов (STL),входящей в библиотеку C++.В то же время, ввиду достаточно высокой проработанности используемых в качествебазовых для приложения библиотек среды wxWidgets,отпала необходимость в создании сложных разветвлённых структур отношенийродитель-потомок (наследования) на уровне кода разрабатываемого приложения. Восновном, наследование свелось к созданию потомков для достаточно большогоупорядоченного множества используемых стандартных компонентов wxWidgets.
1.5.3 wxWidgets
wxWidgetsпредставляет собой набор библиотек для создания легко переносимых приложенийдля платформ Win32, MacOS X,GTK+ и других (X11,Motif, WinCE).Он предоставляет в распоряжение разработчика единый, простой в использовании API.wxWidgets можно использовать сС++, Python, Perl,C#. В отличие от некоторых другихмежплатформенных средств разработки, wxWidgetsпозволяет создавать естественно-выглядящие на любой из перечисленных платформприложения, так как использует собственные графические элементы платформы,вместо их эмуляции. wxWidgets– хорошо продуманный, бесплатный, расширяемый продукт с открытым исходным кодом,что делает его весьма полезным при разработке приложений. Более подробнаяинформация доступна на официальном сайте [14], а также в прочих источникахИнтернета.
Ввиду тогообстоятельства, что в будущем запланировано расширение приложения в целях реализациивозможности использования его под MacOS, для разработки уже первой версиипотребовалось использование межплатформенных SDK,таких как wxWidgets или Qt.Первый был выбран ввиду его простоты и доступности.
1.5.4 FreeImage
Бесплатная библиотека соткрытым исходным кодом, FreeImageиспользуется для работы с данными изображений. FreeImageпредоставляет разработчику удобные средства для загрузки изображений различныхформатов и унифицирует работу с ними. Это библиотека с открытым исходным кодом,поддерживающая работу с такими популярными сегодня графическими форматами, как PNG,BMP, JPEG,TIFF и другими. Для реализацииотдельных аспектов (оговоренных в последующих главах) приложения возникланеобходимость использования подобного рода средств. FreeImageбыла выбрана мною, так как библиотека довольно проста в использовании, быстра,поддерживает многопоточное использование, совместима с всеми 32-х разряднымиверсиями Windiws, кроме того,поддерживает межплатформенную разработку (для Linuxи Mac OSX). FreeImageможет использоваться с С, С++, VB,C#, Delphi,Java, а также в скриптах на Perl,Python, PHPи других. За более полной информацией можно обратиться к официальному сайтупроекта [15].
1.5.5 TinyXML
TinyXML– простой, небольшой, бесплатный С++ анализатор XML.TinyXML – одно из многихсредств, используемых для анализа XMLдокументов, обладает удобным и компактным внешним интерфейсом, не требуетспециальных знаний и длительного обучения для использования. Использовано вреализации некоторых функций приложения для работы с файловой системой.Официальный сайт проекта содержит дополнительную информацию [16].
1.5.6Microsoft Office Visio 2003
MicrosoftOffice Visio 2003 — редактор диаграммиблок-схемдляWindows. Использует векторнуюграфику для создания диаграмм.
Корпорация Visioбыла создана в 1990 г., и она довольно быстро стала известна на рынке благодаряодноименному программному продукту. По данным корпорации, в 2000 г. его применяли около четырех млн. пользователей в 60 странах мира.
MicrosoftVisio 2000, сменившийпредыдущую версию Visio 5.0, — первыйпродукт, вышедший под совместной торговой маркой Microsoftи Visio. В технологическом иорганизационном плане VisioCorporation стала работать всоставе группы Microsoftпо приложениям делового назначения.
Пользовательскийинтерфейс MicrosoftVisio 2003 выполнен втрадиционном стиле продуктов MicrosoftOffice.
Для построения диаграмми схем пользователь может применять два основных приема: рисовать вручную иавтоматически формировать изображение на основе некоторых данных с помощьюширокого набора мастеров.
Например, если выхотите нарисовать блок-схему алгоритма, вычисляющего факториал, то следуетвыбрать в наборе готовых шаблонов. Далее нужно просто перетаскивать мышьюнеобходимые графические объекты на рисунок, вставлять в них нужный текст, соединятьобъекты. При этом можно установить режим автоматического связывания объектов.Кроме набора обычных свойств (текст, оформление, цвет и пр.) каждому объектуможет быть приписана одна или несколько гиперссылок.
Отметим также, чтокроме файлов Visio(.vsd)можно использовать достаточно широкий спектр других файлов, в том числе графическихи .html.
Конечно, это далеко невсе возможности стандартного пакета MicrosoftVisio 2003. Отметим только,что кроме различных диаграмм и графиков он позволяет, например, работать спростейшими географическими картами.
Для специалистовинформационных отделов и разработчиков ПО особый интерес представляют функциипакета MicrosoftVisio Professional,такие как построение схем компьютерных сетей, диаграмм баз данных, структурнойсхемы программ и карт Web-сайтов.При моделировании баз данных разработчик может формировать описаниенепосредственно в среде пакета или импортировать данные из существующих БД.
MicrosoftVisio 2003 представляетбольшой набор средств для визуального моделирования программ – здесь можноиспользовать практически все распространенные типы диаграмм, описываемые спомощью UnifiedModeling Language(UML) версии 1.2. При этомподдерживаются языки программирования C++,Visual Basicи Java.
После установки MicrosoftVisio 2003 на компьютер всредствах разработки, в частности в MicrosoftVisual Studio2005, автоматически прописываются ссылки на пакет. С помощью команды ReverseEngineer UMLModel можно автоматическисформировать описание текущего приложения, которое отображается в видеиерархического дерева в окне UMLNavigator. Надо сказать, что вданном случае мы получаем детальную информацию о программе (включая описаниявнутренних переменных процедуры).
Это весьма краткийобзор функций MicrosoftVisio 2003. Для полученияболее полной информации можно воспользоваться ресурсами из официальногоисточника [13].
2. Проектирование иреализация задачи
2.1 Выбор формальныхмоделей
Любойпроект– это уникальный процесс, в ходе выполнения которого получают уникальныйпродукт. Таким образом, для разработки продукта в проекте, скорее всего, долженприменяться уникальный процесс. Оптимальным же решением при этом являетсяиспользование одной из обобщенных, проверенных на практике методик, адаптировавее для конкретного проекта. Как правило, всегда есть возможность выбора срединескольких начальных жизненных циклов.
Напротяжении десятилетий теоретических исследований и практических разработокбыло разработано множество различных моделей жизненных циклов ПО. Можновыделить наиболее известные из них: каскадная модель, V-образнаямодель, модель быстрого прототипирования, модель быстрой разработки приложений(RAD), инкрементная модель. Каждая из ниххорошо подходит для проектов определённого типа, однако применение её в иныхслучаях может привести к неудаче (большим затратам ресурсов), поэтому к выборунеобходимо отнестись очень внимательно.
Дляразработки редактора “EasyParticles” за основу моделижизненного цикла была взята модель быстрого прототипирования. В отличие откаскадной модели, в основе неё лежит не последовательная линейная структура, ацикловая, поэтому обратная связь между фазами (в целях исправления какой-либопроблемы или недостатка, например) не приводит к значительному увеличениюзатрат и сбою в графике. Использование V-образноймодели не имело смысла, так как она применяется при разработке программногопродукта командой разработчиков, и особо ориентирована на верификацию иаттестацию продукта. Обособленному разработчику было бы весьма непростосправиться с параллельными событиями, возникающими при её использовании. К томуже, как и в каскадной модели, в ней не учтены итерации между фазами. Чтокасается инкрементной модели жизненного цикла, она не могла быть использована,так как определение полной функциональной системы в ней должно осуществляться вначале жизненного цикла, а также, поскольку в данной модели создание однихмодулей завершается значительно раньше других, необходимости в четкоопределенных (также в начале жизненного цикла) интерфейсах. Это недопустимыеусловия для разработки редактора, требования к функциональности, поддерживаемымплатформам, пользовательскому интерфейсу были изменены несколько раз в процессеразработки.
В общем, необходимость применения структурнойэволюционной модели быстрого прототипирования в данном случае выраженадостаточно явно. Признаками тому служат следующие факторы:
— полные требования не известны заранее и непостоянны;
— существует потребность в разработке достаточносложных пользовательских интерфейсов;
— осуществляются временные демонстрации;
— требуется уменьшить неточности в определениитребований; т.е. уменьшается риск создания системы, которая не имеет никакойценности для заказчика;
— разработчики не уверены в том, какую оптимальнуюархитектуру или алгоритмы следует применять;
— системные интерфейсы усложнены;
Созданиемодели быстрого прототипирования было бы невозможным без работ выдающегосяФреда Брукса (“TheMythical Man-Month”,«NoSilver Bullet,the Essenceand Accidentsof Programming»).Его идеи, изложенные в данных книгах, сегодня столь же актуальны, как и в 1975году. Технологии радикально изменили мир, но многие недостатки менеджментапрограммных проектов по-прежнему те же. Десятки лет тому назад Брукс сказал:
«В большинстве проектов первая построеннаясистема едва ли пригодна к употреблению. Она может быть слишком медленной,слишком объемной, неудобной в использовании или обладать всеми тремяперечисленными недостатками. Нет другого выбора, кроме как начать с самогоначала, приложив все усилия, и построить модернизированную версию, в которойрешались бы все три проблемы...
Вслучае, когда в проекте используется новая системная концепция или новаятехнология, разработчик вынужден построить систему, которой впоследствии невоспользуется, поскольку даже при наилучшем планировании невозможно предвидетьдостижение нужного результата”.
Этислова замечательно передают сущность рассматриваемой модели, её основную идею –построение экспериментальных моделей реального приложения, иными словами – прототипирование.
СогласноДжону Коннэллу и Линде Шафер, эволюционным ускоренным прототипом является»легко поддающаяся модификации и расширению рабочая модель предполагаемойсистемы, не обязательно представляющая собой все свойства системы, благодарякоторой пользователи данного приложения получают физическое представление оключевых частях системы до ее непосредственной реализации; это — легкосоздаваемая, без труда поддающаяся модификации, максимально расширяемая,частично заданная рабочая модель основных аспектов предполагаемойсистемы".
Таким образом, прототип — это эквивалентэкспериментальной модели или «макета» в мире аппаратного обеспечения.
Выполнениеэволюционных программ при разработке редактора, как и должно, происходило врамках контекста плана, направленного на достижение предельно высокойпроизводительности. При этом для заказчика был очевиден этот факт, что вомногом облегчило работу. Заказчик принимал активное участие в течение всегопроцесса разработки, что в целом является одним из главных условий успешностиреализации метода прототипирования.
Схемуметода можно изобразить следующим образом:
/>
Рисунок2.1 – Метод быстрого прототипирования
Началожизненного цикла разработки помещено в центре эллипса. В соответствии сосхемой, базовый анализ (на основе предварительных требований) необходимыхсвойств и функций редактора был произведён на начальной стадии разработки (ижизненного цикла в целом). Заказчик и программист совместно определилитребования и спецификации для важнейших частей системы. В результате былполучен документ, описывающий в общих чертах примерные графики и результативныеданные.
Далеебыло осуществлено создание базы данных, пользовательского интерфейса,разработаны соответствующие функции. Другими словами, была создана рабочаямодель – первичный прототип.
Модельбыла продемонстрирована заказчику с целью получения предложений по ееусовершенствованию. Заказчик оценил первичный прототип и совместно спрограммистом определил проблемы, над устранением которых необходимо былоработать в рамках разработки последующего прототипа системы. В основном,изменения коснулись пользовательского графического интерфейса редактора,функциональность ядра системы полностью удовлетворила пользователя на базепервичного прототипа (за исключением небольших ошибок, обнаруженных иисправленных впоследствии).
Всевышеописанные действия представляют собой одну итерацию цикла быстрогопрототипирования. Этот цикл продолжается до тех пор, пока пользователь не будетудовлетворен тем, каким образом система отображает поставленные к ней требования.Команда разработчиков проекта продолжает выполнять этот процесс до тех пор,пока пользователь не согласится, что быстрый прототип в точности отображаетсистемные требования.
Приразработке текущего проекта было создано два быстрых прототипа. Послемодификации второго была получена окончательная версия системы, официальноодобренная пользователем. Именно на этом этапе настройки ускоренный прототип редакторастал полностью действующей системой, которая заменила собой частичную систему,полученную в итерационном цикле прототипирования.
Использованиеданной модели не раз оправдало себя в течение разработки. В целом, онопозволило решить следующие проблемы:
— исходя из реакции заказчиков на демонстрации разрабатываемого продукта,разработчиком были получены сведения об аспектах необходимого поведениясистемы, благодаря чему количество неточностей в требованиях свелось минимуму;
— минимизирование вероятности искажения информации и возникновения недоразуменийпри определении системных требований, что несомненно привело к созданию болеекачественного конечного продукта;
— при разработке образовывались постоянные, видимые признаки прогресса ввыполнении проекта, благодаря чему заказчики чувствовали себя уверенно;
— благодаря меньшему объему доработок были уменьшены затраты на разработку;
— благодаря тому, что проблемы, как правило, выявлялись до привлечениядополнительных ресурсов, сократились общие затраты;
— было обеспеченоуправление рисками;
2.2 Структурная модель приложения
Приложениесостоит из двух основных сущностей:
а)очередь эмиттеров;
б)оконно-интерфейсная часть;
Сущности,в свою очередь состоят из множества функционально-логических блоков.
Очередьэмиттеров представляет собой программируемый контейнер, предназначенный дляхранения параметров набора эмиттеров и их частиц, а также отображения в режимереального времени. Очередь также определяет режимы смешивания и порядокрисования наборов частиц друг относительно друга. Это позволяет создаватьразличные эффекты наложения.
Отдельновзятый набор частиц представлен внутренними структурами данных эмиттера. Здесьхранятся все параметры эмиттера и каждой его частицы:
а)для эмиттера:
1)координаты в двумерной декартовой системе;
2)скорость;
3)размеры;
4)значения разброса частиц;
5)стартовая задержка и длительность генерации;
б)для частицы:
1)текстура;
2)время жизни;
3)скорость по осям;
4)гравитация по осям;
5)значения начальных и конечных растяжений;
6)значения начального и конечного цветов по каналам;
Дляреализации интерфейсной части были использованы графические объектывышеописанного межплатформенного движка wxWidgets.
Корневымэлементом интерфейсной части является основной фрейм. Основной фрейм служит длярасположения фрейма ввода данных, фрейма управления очередью эмиттеров, фреймавывода. Также основному фрейму принадлежат системное меню, панели инструментови статуса.
Фреймввода данных предназначен для ввода вышеозначенных параметров текущегоэмиттера. В редакторе всегда имеется текущий эмиттер, если их число большенуля. Если же оно равно нулю, инструменты фрейма ввода блокируются. Приизменении текущего эмиттера происходит соответствующее обновление данныхинструментов фрейма ввода.
Фреймуправления очередью эмиттеров представляет собой панель со схематическимотображением отдельных эмиттеров в виде пиктограмм. К функциям фрейма относятсядобавление и удаление эмиттеров, копирование эмиттера со всеми его параметрами,изменение текущего эмиттера, а также порядка прорисовки эмиттеров. Длякопирования и удаления эмиттеров при активном фрейме управления очередью можноиспользовать горячие клавиши (Ctrl+V,Ctrl+X,соответственно).
Фреймвывода объединяет в себе всю функциональность вывода графических данныхприложения. Для максимально быстрого вывода используется низкоуровневая работас аппаратным обеспечением видеосистемы, осуществляемая посредством драйвера OpenGL.Доступ к платформенно-независимому конвейеру OpenGLосуществляется, в свою очередь, через интерфейс wxWidgets.Именно на уровне фрейма вывода осуществлено связывание оконной системы ифункциональности рисования очереди эмиттеров, не зависящей от конкретного окнаи работающая с буферами OpenGL.Средства wxWidgets используют дляэтого те или иные системные библиотеки, в зависимости от целевой платформы. ДляWindows это WGL,для MacOS X– AGL, а также стандартные Carbon(дляС++) и Cocoa(ObjectiveС).
Дополнительнофрейм вывода позволяет при помощи мыши перемещать эмиттеры, изменять ихразмеры. Также поддерживается перенос рабочей (текущей отображаемой) области рисования.Для этого необходимо, во-первых, активировать режим переноса, использовавклавишу Space. Затем, используямышь, осуществить перенос области в нужном направлении и на необходимоерасстояние. Для выхода из режима переноса рабочей области необходимо повторнонажать клавишу Space. Необходимоотметить, что в режиме переноса рабочей области возможности переноса эмиттерови изменения их размеров отключаются.
Системноеменю имеет следующую структуру:
— меню “Файл”, отвечающее за общий сброс, сохранение и загрузку, выход из приложения;
— меню “Очередь”, отвечающее за установку режима отображения эмиттеров (Playback,Loop playback,Static), добавление иудаление текущего эмиттера, копирование эмиттера и набора его параметров, сбросвсех эмиттеров;
— меню “Информация”, позволяющее получить информацию о способах использованияредактора, а также о разработчике;
Панельинструментов содержит следующие компоненты:
а)функции установки режима отображения эмиттеров:
1)Playback;
2)Loop playback;
2)Static;
б)функции сохранения и загрузки:
1)Save;
2)Load;
в)функции настройки отображения:
1)Back color;
2)Back image;
3)режимсмешивания;
Панель статуса имеет дваполя: количество отображённых за секунду кадров, число частиц, число примитивов,быстрая подсказка (по ситуации).
Получить информацию овнутренней структуре приложения можно, обратившись к диаграмме классов(Приложение Г).
2.3 Функциональная модельприложения
Разработанный редакторимеет шесть базовых функциональных блоков: настройка очереди эмиттеров,обновление, отображение, ввод/вывод, настройка отображения и работа сосправочной системой приложения (в базовой версии сводится к получению общейинформации о функциональности редактора и разработчике, впоследствиипланируется расширение).
Настройка очередиэмиттеров, в свою очередь, состоит из на набора функций по управлению очередью(добавление эмиттеров, удаление эмиттеров, копирование эмиттеров с переносом ихпараметров) и набора функций по установке параметров текущего эмиттера и егочастиц.
Функция отображенияреализует вывод на экран создаваемых эффектов.
Функции ввода и выводапозволяют пользователю сохранять текущий проект, а именно – данные о эмиттерахи о дополнительных параметрах отображения, на внешний носитель, и загружатьпроекты, которые были сохранены ранее.
Функции настройкиотображения состоят в установке дополнительных параметров отображения(перечисленных в предыдущем подразделе).
Получить болеедетальную информацию о множестве и структуре интерфейсных функций приложенияможно, обратившись к диаграмме вариантов использования (Приложение Д). На нейотображена декомпозиция крупнейших интерфейсных блоков. Диаграмма позволяет внаглядной форме представить набор действий, осуществляемых пользователем,которыми определяется работа редактора.
2.4 Информационная модельприложения
Информационнаямодель приложения отражает потоки информации, проходящие между его модулями ивнешними сущностями.
Разрабатываемыйредактор частиц является однопользовательским приложением, так как поддерживаетинтерфейс одновременно лишь с одним пользователем. Таким образом, первойвнешней сущностью является пользователь.
Данныео частицах, обработанные редактором, выводятся на внешний носитель в видетекстовых файлов формата XML.Позже эти файлы могут быть использованы как редактором, так и поставляемымсовместно с ним инструментарием в контексте целевого приложения. Таким образом,второй внешней сущностью является носитель данных.
Занепосредственный приём данных эмиттеров от пользователя отвечает инструментарийфрейма ввода. Библиотеки операционной системы предоставляют для этого всёнеобходимое, а использование предкомпиляторных “фильтров” wxWidgetsпозволяет и вовсе забыть о платформе.
Послеввода данные направляются в первую основную сущность приложения – очередьэмиттеров. Там они хранятся, используясь при выводе (некоторые полямодифицируются при этом).
Всвою очередь, ввод управляющих сигналов осуществляется через аналогичныеинструменты панели инструментов. Эти данные помещаются в служебные поля очередиэмиттеров, а также фрейма вывода.
Обменданными с внешними носителями осуществляется по соответствующим управляющимкомандам. При сохранении осуществляется съём данных очереди эмиттеров,параметров отображения, хранящихся в фрейме вывода, прочей служебнойинформации, характеризующей состояние приложения, которые форматируютсяустановленным образом (используется инструмент TinyXML)и выводятся. При загрузке происходит прямо противоположная последовательностьдействий.
Обобщаявышесказанное, к основным потокам данных приложения можно отнести:
а)ввод пользователем в систему параметров эмиттеров:
1)координаты в двумерной декартовой системе;
2)скорость;
3)размеры эмиттера;
4)значения разброса частиц;
5)стартовая задержка и длительность генерации;
б)ввод пользователем в систему параметров частиц эмиттера:
1)текстура;
2)время жизни;
3)скорость по осям;
4)гравитация по осям;
5)значения начальных и конечных растяжений;
6)значения начального и конечного цветов (32bit),по каналам;
в)вывод графической информации системы эмиттеров в буфер изображения;
Графически информационнаямодель приложения представлена в Приложении В, на диаграмме потоков данных.
2.5 Объектная модельприложения
Таккак приложение было разработано с использованием возможностейобъектно-ориентированного языка С++, следует раскрыть его объектную структуру.Подробно объектная структура программного средства описана в Приложении Г,здесь же можно привести общий обзор системы классов.
а)класс MyApp, отвечает заинициализацию приложения, создаётся и управляется полностью из среды wxWidgets.Это корневой класс всей проектируемой части приложения.
б)модуль очереди эмиттеров. Включает в себя:
1)класс ParticleSystemChain,то есть непосредственно саму очередь; в системе существует singleton-объектданного класса;
2)содержащиеся в очереди эмиттеры – объекты класса ParticleSystem;
3)для формирования и использования корректных OpenGLтекстур на основании битовых изображений используются объекты класса MyTexture.
в)класс MainFrame – корневойкласс оконного пользовательского интерфейса; в системе существует singleton-объектданного класса;
г)класс PSChainFrameпредставляет собой окно управления очередью систем;
д)объекты PSLabel применяются в PSChainFrameдля представления эмиттеров, представляют собой пиктограммы;
е)PSInputFrame используется для вводапользовательских данных активной системы;
ж)объекты классов MySpinCtrldи MySpinEditCtrld – пользовательскиеэлементы управления, используемые для ввода чисел с плавающей точкой изуказанного диапазона, применяются в PSInputFrame;
з)PSOutputFrame используется дляотображения результатов работы приложения (вывода вычисленных графическихпримитивов – частиц); объект MyCanvas– предоставляется OpenGLв качестве контекста визуализации;
Это общий переченьразработанных в рамках программного средства классов с кратким описанием ихфункциональности. Взаимосвязи между ними и другими, менее значительными,классами, а также внутренняя структура классов в более полном виде раскрываетсяв Приложении Г.
2.6 Требования к программным,аппаратным ресурсам и ОС
Длясборки приложения необходимо наличие набора встраиваемых (статических)библиотек среды wxWidgets,установленных в системный каталог (или в один из каталогов поиска статическихбиблиотек, указанных в настройках среды разработки MicrosoftVisual Studio2005 и в свойствах проекта). Для корректной работы приложения необходимоналичие в системе динамической библиотеки OpenGL(любой версии, по умолчанию с OSWindows поставляется версия1.0). Драйвер OpenGL используетсядля растеризации графических данных, генерируемых редактором.
Приложениетребует не более 30 MB оперативнойпамяти, 20 MB – виртуальной, 40 MBдискового пространства.
Минимальноеразрешения дисплея монитора, требуемое для корректной работы приложения,составляет 1024x768 точек.
Приложениеработает под управлением любой OСWindows (версии не ниже WindowsXP SP2).
Крометого, для корректной работы приложения, собранного в MicrosoftVisual Studio2005, необходимо наличие в системе установленных специальным образом библиотек(так называемых манифестов), иначе приложение не запустится. В качествеальтернативы можно собрать приложение с использованием MicrosoftVisual Studio2003, однако при этом будет использован графический пользовательский интерфейсстарого образца.
3. Тестирование
3.1 Анализ надежности
Испытанияпроводятся с целью выявления отклонений в работе программы и результатах еёфункционирования, оценки причин таких отклонений. Отклонения полученныхрезультатов от эталонов используются для оценки качества программы.
Основнымметодом обнаружения ошибок при проведении испытаний программы являлосьтестирование, в котором целесообразно выделить три стадии:
— тестирование для обнаружения ошибок в программе, где выявлялись все отклонениярезультатов функционирования реальной программы от заданных эталонных значений;
— тестирование для диагностики обнаруженных искажений результатов, сцелью обнаружения инструкций и данных,явившихся причиной отклонения результатов от эталонных при тестировании дляобнаружения ошибок;
— тестированиедля контроля выполненных корректировок программы и данных, где подтверждаласьправильность выполненной корректировки.
Говоряо тестировании, понимается проверка программы не только в статическом режиме,когда обнаруживаются ошибки кода программы, но и динамическая проверка,включающая контроль адекватности реакции системы на заявки пользователя иповедения системы при возникновении недопустимых ситуаций.
Найденные ошибкиустранялись, процесс продолжался до тех пор, пока работа приложения не былапризнана удовлетворительной.
3.2 Тестовые примеры
Притестировании был проведен ряд тестов различной направленности:
— тест корректности вводимых пользовательских данных, в рамках которого былапроверена система ввода всех видов данных, используемых приложением, спопытками ввода некорректных данных;
— тест работоспособности с граничными значениями параметров; любое приложениенеобходимо проверять на работоспособность в граничных состояниях, так как, всилу своей неочевидности и низкой вероятности возникновения, это, как правило, наиболееузкие места в функциональности;
— тест корректностиработы приложения на ПК с различными конфигурациями (драйверами графическогоускорителя); приложения, использующие низкоуровневую функциональность драйвера(или близкую к ней), необходимо дополнительно тестировать на совместимость сразличными разновидностями драйверов данного типа. В случае с разрабатываемприложением, необходимо выполнить проверку на корректность его работы сразличными драйверами видеосистемы, так как приложение используетнизкоуровневые возможности OpenGLв качестве своей осевой функциональности.
3.3 Реакция программына тесты
Спомощью встроенного компилятора были обнаружены синтаксические ошибки. Стоитотметить, что допущение множества тривиальных синтаксических ошибок являетсянормальным явлением при разработке программного средства, поэтому рекомендуетсякак можно чаще выполнять рекомпиляцию текущего разрабатываемого программногомодуля. Это позволяет выявлять такие ошибки и избегать их накапливания. Впротивном случае происходит сильное усложнение процесса их локализации вфинальной версии модуля, так как они начинают влиять друг на друга. В такойситуации бывает тяжело отделить одну ошибку от другой.
Послеуспешной компиляции и сборки приложения, непосредственно в процессетестирования, были обнаружены и устранены ошибки времени исполнения. Изнаиболее трудно-устранимых можно отметить ошибку приведения данных типов сплавающей запятой при пользовательском вводе (что приводило к их неявному искажению),а также ошибки проектирования пользовательского интерфейса, в связи с чемпоследний был целиком переработан несколько раз. При тестировании приложения сграфическим ускорителем от фирмы ATIбыли выявлены ошибки инициализации текстурных данных, из-за чего нарушался ихвывод. Из ошибок работы приложения при установленных граничных значенияхпараметров можно выделить ошибку генерации частиц при заданной ширине и/иливысоте эмиттера, равной нулю. При этом для частиц генерировались координаты,сильно выходящие за пределы границ эмиттера. Эту ошибку можно назватьлогической ошибкой программы.
При устранениинайденных ошибок отладка программы осуществлялась встроенным отладчиком MSVisual Studio2005.
3.4 Вывод порезультатам тестирования
Цельпроведения испытаний состояла в том, чтобы рассмотреть все возможные вариантыработы программы, протестировать ее в нормальных, исключительных иэкстремальных условиях, выявить недостатки и устранить их, если таковые имелиместо.
Врезультате испытаний на контрольных примерах было доказано, что данная программаработает согласно заданному алгоритму. Все ошибочные ситуации были рассмотрены,ошибки – устранены.
4. Применение программы
4.1 Назначениепрограммы
Программапредназначена для создания и редактирования сложных графических эффектовчастиц. В процессе разработки была обеспечена реализация программой следующегонабора функций:
— управление динамическим набором эмиттеров (систем частиц);
— управление частицами каждого эмиттера;
— управление общими параметрами рисования;
— ввод и вывод данныхна внешние носители;
4.2 Инсталляцияпрограммы
Разработанноепрограммное средство не нуждается в инсталляции. Однако следует заметить, чтодля работы приложения необходимо наличие в системе динамической библиотеки OpenGLлюбой версии (с MSWindows по умолчаниюпоставляется версия 1.0).
Кроме того, длякорректной работы приложения, собранного в MicrosoftVisual Studio2005, необходимо наличие в системе установленных специальным образом библиотек(так называемых манифестов), иначе приложение не запустится. В качествеальтернативы можно собрать приложение с использованием MicrosoftVisual Studio2003, однако при этом будет использован графический пользовательский интерфейсстарого образца. Более подробно о манифестах, их типах и назначениях, можнопрочитать на официальном сайте корпорации Microsoft[13].
4.3 Структура входныхданных
Входными даннымиприложения служат параметры эмиттеров, задаваемые пользователем, а такжепараметры отображения. Более подробно со структурой входных данных можноознакомиться в подразделе 1.1, или на диаграмме потоков данных (Приложение В).
4.4 Диалог спользователем
Диалог с пользователемосуществляется посредством панели состояния, располагающейся внизу экранаприложения. На ней осуществляется вывод текущей частоты обновления картинки, атакже контекстные подсказки, содержимое которых зависит от текущих действийпользователя.
При попытке выхода изприложения с несохранёнными данными проекта осуществляется запрос пользователяо необходимости выполнить сохранение данных.
При запросе справочнойинформации системы помощи или информации о разработчике осуществляетсяактивация диалоговых окон с соответствующими запросу данными.
В остальном, с учётомтипа и назначения приложения, используемого в нём интуитивно понятного,продуманного графического пользовательского интерфейса, необходимость вдополнительной обратной связи с пользователем отпадает.
4.5 Форма представлениявыходных данных
Выходныеданные формируются, как уже было отмечено выше, в нескольких формах. Можнопросматривать выходную информацию в графическом виде непосредственно на экранередактора. Также разработчик приложения, использующий редактор (предоставляемыйразработчику исходный код для вывода эффектов частиц), может выводить данные в окносвоего приложения (предварительно связав его с OpenGLсредствами ОС). Наконец, можно просматривать выгруженные на диск выходныеданные с помощью любого текстового (XML)редактора.
5. Оптимизациязрительного взаимодействия оператора со средствами отображения информации паоснове ЭЛТ
5.1 Особенностизрительного восприятия информации и формирование утомления зрительногоанализатора оператора
Зрительноевосприятие — совокупность процессов построения зрительного образа окружающегомира. Из этих процессов более простые обеспечивают восприятие цвета, котороеможет сводиться к оценке светлоты, или видимой яркости, цветового тона, илисобственно цвета, и насыщенности как показателя отличия цвета от серого равнойс ним светлоты. При этом основные механизмы цветового восприятия имеютврожденный характер и реализуются за счет структур, локализованных на уровнеподкорковых образований мозга. Более филогенетически поздними являютсямеханизмы зрительного восприятия пространства, в которых происходит интеграциясоответствующей информации о пространстве, полученной также от слуховой,вестибулярной, кожно–мышечной сенсорных систем. В пространственном зрениивыделяют два основных класса перцептивных операций, обеспечивающих константноевосприятие. Одни позволяют оценивать удаленность предметов на основебинокулярного и монокулярного параллакса движения. Другие позволяют оценитьнаправление. В основном пространственное восприятие обеспечивается врожденнымиоперации, но их окончательное оформление происходит в приобретаемом в течениежизни опыте практических действий с предметами. Пространственное восприятиеявляется основой восприятия движения, которое также осуществляется за счетврожденных механизмов, обеспечивающих детекцию движения. Более сложнымиоперациями зрительного восприятия является операции восприятия формы, которые ив филогенезе, и онтогенезе формируются достаточно поздно. Основой выступаетвосприятие пространственных группировок как объединение однотипных элементов,расположенных в достаточно узком зрительном поле.
Впроцессе работы на компьютере, даже отвечающем всем требованиям ТСО, присоблюдении эргономических параметров рабочего места и правильной организациирежимов труда и отдыха пользователь все-таки может испытывать определеннуюзрительную и мышечную усталость, физический и психологический дискомфорт,которые усиливаются, если не принять профилактических мер. При использованииуже устаревших на сегодняшний день (в отношении дисплеев ПК) ЭЛТ, этот эффектпроявляется особенно сильно, так как нагрузка на органы зрения в этом случаегораздо выше. При этом знание и осуществление профилактических мер становитсяабсолютно необходимым условием длительной и безопасной для здоровья работы сдисплеем.
Кпрофилактическим мерам относятся комплексы упражнений для глаз, для снятияобщего и локального утомления с различных групп мышц организма, для стимуляциидеятельности нервной, сердечно-сосудистой, дыхательной систем, для повышениядвигательной активности и умственной работоспособности.
Наиболеераспространенным недомоганием у пользователей ПК является зрительное утомление,которое при отсутствии надлежащих мер и при продолжении работы может проявитьсяв виде частого моргания, зуда и жжения в глазах, рези, слезотечения и другихреакций.
Вкачестве профилактических мер для снижения утомления глаз, улучшениякровоснабжения глазного яблока, релаксации глазодвигательных мышц рекомендуетсяпроводить специальные упражнения для глаз, взрослым пользователям – во времярегламентированных перерывов вместе с другими комплексами физическихупражнений, а студентам – через каждые 20-25 минут работы. При появлениизрительного дискомфорта эти упражнения следует проводить индивидуально,самостоятельно и раньше указанного времени.
Специалистами-медикамии гигиенистами разработано большое количество разнообразных упражнений,направленных на восстановление и защиту от перегрузок органов зренияупражнений. Они широко представлены, например, в источнике [8].
Приведёмпример одного из наиболее простых в реализации упражнений. Упражнение называется«пальминг» и состоит в следующем. Пальцы рук, сложенные вместе,следует перекрестить в центре лба. При этом ладони накроют глазные впадины,полностью исключая доступ света, и в то же время не будут сжимать глазныеяблоки, оставляя возможность свободно двигать веками. В процессе такого отдыхаорганов зрения, т. е. в период прекращения к ним доступа света, происходятхимическое восстановление рецепторов глаз и расслабление мышечных волокон,перенесших напряжение после интенсивных потоков образов. Подобное искусственноезатмение зрения является одним из лучших упражнений для глаз, значительноускоряя процесс расслабления глазных мышц и улучшая кровообращение.Двухминутный пальминг восстанавливает функциональные свойства сетчатки глаза.
Разумеется,перед возможной систематической работой с дисплеями для гигиены зрения и егопрофилактического контроля необходимо предварительно пройти всестороннее обследованиеу окулиста и в дальнейшем регулярно, не менее одного раза в год, повторять этообследование.
При возникновениизаметного зрительного дискомфорта в процессе работы, несмотря на хорошеекачество монитора, правильную эргономическую организацию труда и соблюдениережимных требований, а также выполнение указанных упражнений, следуетограничить время работы с дисплеем. В этом случае должна быть либо увеличенадлительность перерыва для отдыха, либо произведена смена деятельности.
5.2 Инженерно-психологическиетребования к средствам отображения информации (СОИ) и их расположению в рабочемпространстве
Средстваотображения информации предназначены для получения человеком сведений осостоянии объекта управления, ходе производственного процесса, наличииэнергетических ресурсов, состоянии каналов связи и т. д. Эти данныепредъявляются человеку в виде количественных и качественных характеристик.Средства отображения информации могут применяться, например, в тех случаях,когда человек не может непосредственно наблюдать за технологическим процессомвследствие его территориальной удаленности, вредности или опасности при контактес предметом труда.
Средстваотображения информации способствуют повышению точности непосредственногонаблюдения, с их помощью информация предъявляется в более удобной длявосприятия и обработки форме. Широкое внедрение систем дистанционного управленияпривело к тому, что иногда СОИ становятся единственным источником информации обуправляемом объекте и рабочем процессе. В этом случае человек имеет дело не среальными объектами, а с их моделями, т. е. с информацией, организованной всоответствии с определенной системой правил и подаваемой на средства ееотображения. Информационная модель позволяет человеку анализировать состояниеуправляемого объекта, принимать решения и осуществлять контроль и управлениепроцессом производства.
Эргономическиетребования к визуальным СОИ устанавливают необходимые производственные,яркостные, частотные характеристики зрительных образов, а также способы ихразмещения на рабочем месте. Нарушение этих требований приводит к снижениюэффективности рабочего процесса, повышению уровня опасности для здоровья ижизни работников и прочим негативным результатам.
Всеэргономические требования изложены в соответствующих ГОСТах (ГОСТ 21829- 76,ГОСТ 21480-76, ГОСТ 21837-76, ГОСТ 22902-78).
Остановимсяна основных требованиях к мониторам и характеристиках изображения на экране.
Монитор– это, как правило, единственное устройство, «лицом к лицу» с которымпользователь проводит не один год. Удобочитаемость информации на экране зависитот четкости элементов изображения. Основными параметрами изображения на экранемонитора являются яркость, контраст, размеры и форма знаков, отражательнаяспособность экрана, наличие или отсутствие мерцаний.
Основныенормируемые визуальные характеристики мониторов и соответствующие допустимыезначения этих характеристик представлены в таблице 5.1.
Таблица5.1 – Некоторые нормируемые визуальные параметры мониторов [9]Параметры Допустимые значения Яркость знака или фона (измеряется в темноте) 35-120 кд/м2 Контраст От 3:1 до 1,5:1 Временная нестабильность изображения (мерцания) Не должна быть зафиксирована более90% наблюдателей Угловой размер знака 16-60 Отношение ширины знака к высоте 0,5-1,0 Отражательная способность экрана (блики) не более 1% Неравномерность яркости элементов знаков не более (25%) Неравномерность яркости рабочего поля экрана не более (20%) Формат матрицы знака не менее 7 * 9 элементов изображения Размер минимального элемента отображения (пикселя) для монохромного монитора, мм. 0,3 Допустимое вертикальное смещение однотипных знаков, % от высоты матрицы не более 5 Допустимая пространственная нестабильность изображения (дрожание по амплитуде изображения) при частоте колебаний в диапазоне от 0,5 до 30 Гц, мм
не более 2L*10-4 (L-расстояние наблюдения, мм.)
Крометого, компьютеры и мониторы, а также организация рабочих мест операторов должнысоответствовать принятым на территории Республики Беларусь санитарным правилами нормам [7], касающимся охраны зрения пользователей персональных компьютеров:
Конструкциямонитора должна обеспечивать возможность фронтального наблюдения экрана путемповорота корпуса в горизонтальной плоскости вокруг вертикальной оси в пределах30° и в вертикальной плоскости вокруг горизонтальной оси в пределах 30° сфиксацией в заданном положении. Дизайн монитора должен предусматривать окраскукорпуса в спокойные мягкие тона с диффузным рассеиванием света.
Корпусмонитора и ПК, клавиатура и другие блоки и устройства ПК должны иметь матовуюповерхность одного цвета и не иметь блестящих деталей, способных создаватьблики. На лицевой стороне корпуса монитора не рекомендуется располагать органыуправления, маркировку, какие-либо вспомогательные надписи и обозначения. Принеобходимости расположения органов управления на лицевой панели они должнызакрываться крышкой или быть утоплены в корпусе.
Экранвидеомонитора должен находиться от глаз пользователя на оптимальном расстоянии600-700 мм, но не ближе 500 мм с учетом размеров алфавитно-цифровых знаков исимволов.
Рабочееместо с монитором и ПК должно быть оснащено легко перемещаемым пюпитром длядокументов.
Уровень глаз привертикально расположенном экране монитора должен приходиться на центр или 2/3высоты экрана. Линия взора должна быть перпендикулярна центру экрана и оптимальноеее отклонение от перпендикуляра, проходящего через центр экрана в вертикальнойплоскости, не должно превышать 5°, допустимое — 10°.
5.3 Требования корганизации, качественным и количественным характеристикам освещения рабочегоместа оператора и их реализация. Оптимизация режима труда и отдыха оператора
Рациональноеосвещение помещений – один из наиболее важных факторов, от которых зависитэффективность трудовой деятельности человека.
Хорошееосвещение необходимо для выполнения большинства задач оператора. Для того чтобыспланировать рациональную систему освещения, учитывается специфика рабочегозадания, для которого создается система освещения, скорость и точность, скоторой это рабочее задание должно выполняться, длительность его выполнения и различныеизменения в условиях выполнения рабочих операций.
Нормамидля данных работ установлена необходимая освещенность рабочего места Ен=300лк(средняя точность работы по различению деталей размером от 1 до 10 мм).
Дляосвещения рабочего места оператора обычно используются люминесцентные лампы –они имеют ряд преимуществ перед лампами накаливания: их спектр ближе кестественному, они имеют большую экономичность (больше светоотдача) и срокслужбы (в 10-12 раз). Наряду с этим имеются и недостатки: их работа иногда сопровождаетсяшумом, они хуже работают при низких температурах, имеют малую инерционность.
Вобщем, все основные требования к освещению помещений учреждений применимы такжек освещению рабочих мест у видеоэкранов дисплейных устройств. Однако имеетсяцелый ряд особенностей работы у видеоэкранов, которые необходимо учитывать. Крометщательного ограничения отражения это связывается, прежде всего, с правильнымвыбором уровня освещенности и проблем уменьшения скачков яркости при смене полязрения. Источники света, такие как светильники и окна, которые дают отражение отповерхности экрана, значительно ухудшают точность знаков. Наиболее важнымявляется соотношение яркостей при нормальных условиях работы, т.е. освещенностьна рабочем месте около 300 лк, и средняя плотность заполнения видеоэкрана. Отражение,как на экране, так и на рабочем столе и клавиатуре, влечет за собой помехифизиологического характера, которые могут выразиться в значительном напряжении,особенно при продолжительной работе. Отражение, в том числе и от вторичных источниковсвета, должно быть сведено к минимуму. Для защиты от избыточной яркости окон могутбыть применены занавеси, шторы и экраны. Использование дополнительного освещениярабочего стола, например, для освещения документов с нечетким шрифтом,увеличивает соотношение яркостей между документацией и экраном и являетсянежелательным без соответствующей регулировки яркости экрана.
Впомещении, предназначенном для работы на компьютере, должно иметься как естественное,так и искусственное освещение.
Чтокасается естественного освещения, лучше всего, если окна в комнате выходят насевер или северо-восток. Как уже было сказано, в поле зрения пользователя недолжно быть резких перепадов яркости, поэтому окна желательно закрывать шторамилибо жалюзи. Уровень естественного освещения нормируется коэффициентоместественной освещенности (КЕО) — это отношение естественной освещенностивнутри помещения Евн к одновременному значению наружной горизонтальнойосвещенности Ен. Освещенность Е измеряется в люксах (Лк). Фактическаяосвещенность должна быть больше или равна нормируемой. При эксплуатации зданийнеобходимо поддерживать светоотдачу и светопропускаемость окон, т. е.производить их своевременную чистку. При незначительном выделении пыли – 4 разав год.
Искусственноеосвещение может быть общим и комбинированным, внутренним инаружным. Искусственное освещение обеспечивается электролампами различноймощности, заключенными в специальную арматуру (светильники, различных типов иисполнений).
Искусственноеосвещение рабочего места оператора должно быть общим и равномерным,использование одних только настольных ламп недопустимо.
Однимиз главных способов повлиять на процессы утомления оператора являетсяустановление соответствующих режимов труда.
Прираспределении работ в течение недели следует учитывать, что работоспособностьувеличивается в первые дни недели, достигает наивысшего уровня натретий-четвертый день, а затем снижается.
Распределениеработ в течение смены должно учитывать, что период вырабатывания у операторовПК составляет от 10 до 40 минут (в послеобеденное время период вырабатываниясокращается). Период устойчивой работоспособности продолжается около двухчасов; период наступления утомления и спада работоспособности наступает после1,5-2,0 часов устойчивой работоспособности (во второй половине рабочего дняпериод утомления более выражен).
Режимытруда и отдыха при работе с ПК в течение смены должны организовываться взависимости от вида и категории трудовой деятельности.
Видытрудовой деятельности разделяются на 3 группы:
а)группа А — работа по считыванию информации с экрана ПК с предварительнымзапросом;
б)группа Б — работа по вводу информации;
в)группа В — творческая работа в режиме диалога.
Привыполнении в течение рабочей смены работ, относящихся к разным видам трудовойдеятельности, за основную работу с ПК следует принимать такую, которая занимаетне менее 50% времени в течение рабочей смены или рабочего дня.
Длявидов трудовой деятельности устанавливается 3 категории тяжести и напряженностиработы с ПК, которые определяются:
а)для группы А — по суммарному числу считываемых знаков за рабочую смену, но неболее 60 000 знаков за смену;
б)для группы Б — по суммарному числу считываемых или вводимых знаков за рабочуюсмену, но не более 40 000 знаков за смену;
в)для группы В — по суммарно времени непосредственной работы с ПК за рабочуюсмену, но не более 6 часов за смену.
Количествоперерывов на отдых в принципе должно соответствовать количеству выраженных физиологическихспадов функционирования тем организма, возникающих при утомлении во времятрудового процесса. Лучше всего подойти к этому вопросу сугубо индивидуально ипровести соответствующие исследования. А в общем случае времярегламентированных перерывов в течение рабочей смены устанавливается взависимости от ее продолжительности, вида и категории трудовой деятельности(таблица 5.2).
Таблица5.2 – Время регламентированных перерывов в зависимости от продолжительностирабочей смены, вида и категории трудовой деятельности с ПККатегория работы с ПК Уровень нагрузки за рабочую смену при видах работ с ПК Суммарное время регламентированных перерывов, мин. группа А, кол-во знаков группа Б, кол-во знаков группа В, час. при 8-часовой смене при 12-часовой смене I до 20000 до 15000 до 2,0 30 70 II до 40000 до 30000 до 4,0 50 90 III до 60000 до 40000 до 6,0 70 120
Времяперерывов дано при соблюдении оптимальных режимов труда, в противном случаевремя регламентированных перерывов следует увеличить на 30%.
Приработе с графическими элементами менее 0,5 мм, длительность сосредоточенного наблюдения должна быть не более 50% времени смены.
Продолжительностьнепрерывной работы с ПК без регламентированного перерыва не должна превышать 2часов.
Примногосменной работе, что актуально для диспетчеров, да и взаимоотношения с Internetчасто вынуждают к такому режиму, физиологически рациональное время начала иокончания работы смены находится в следующих интервалах: 6 — 8 часов, 14 — 16часов, 0 — 4 часа.
Приработе с ПК в ночную смену (с 22 до 6 часов), независимо от категории и видатрудовой деятельности, продолжительность регламентированных перерывов должнаувеличиваться на 60 минут. При 8-часовой рабочей смене и работе на ПКрегламентированные перерывы следует устанавливать:
а)I категория работ — через 2 часа отначала рабочей смены и через 2 часа после обеденного перерывапродолжительностью 15 минут каждый;
б)II категория работ — через 2 часа отначала рабочей смены и через 1,5 — 2 часа после обеденного перерывапродолжительностью 15 минут каждый или продолжительностью 10 минут через каждыйчас работы;
в)III категория работ — через 1,5 — 2часа от начала рабочей смены и через 1,5 — 2 часа после обеденного перерывапродолжительностью 20 минут каждый или продолжительность 15 минут через каждыйчас работы.
При12-часовой рабочей смене регламентированные перерывы должны устанавливаться впервые 8 часов работы аналогично перерывам при 8-часой рабочей смене, а втечение последних 4 часов работы, независимо от категории и вида работ, каждыйчас продолжительностью 15 минут.
Принесоблюдении принятых санитарных норм СанПиН 9-131 РБ 2000, а также требований,которых необходимо придерживаться во избежание ошибок, которые может допуститьв процессе работы оператор, приводит к психофизиологическим перегрузкамоператора.
6. Обоснованиеэкономической целесообразности разработки ПС “EasyParticles”
6.1 Общаяхарактеристика разрабатываемого ПС ВТ
Особенностьюсовременных бизнес процессов в любой отрасли общественной деятельности являетсяавтоматизация сбора и обработки информации для принятия управленческих решений.Вместе с тем, автоматизация невозможна без использования программных продуктов.Решение любой информационной задачи связано с применением не только системныхпрограмм, но и разнообразных программных средств – приложений.
Разработкапроектов программных средств требует затрат разнообразных и, не редкозначительных объемов, ресурсов (трудовых, материальных, финансовых). В связи сэтим, разработка и реализация каждого проекта должна быть обоснована, кактехнически, так и экономически.
Проектстоит разрабатывать, если он дает определенные преимущества по сравнению сизвестными передовыми аналогами или, в крайнем случае, по сравнению ссуществующей практикой. Поэтому, до того как приступить к разработке проектапрограммного средства, специалист должен, использую соответствующие методы,найти наиболее рациональное программное решение, обеспечивающее высокийтехнический уровень программы и дающее существенную экономию ресурсов, как приразработке проекта в научно-технической организации (у разработчика), так и приего реализации у пользователя (покупателя, заказчика).
Программноесредство функционального назначения “EasyParticles” – графическийредактор, разработан на C++с использованием MSVisual Studio2005 и ряда специализированных библиотек, является ПС 1 группы сложности.
Разрабатываемоепрограммное средство относится к 1-й группе сложности. По степени новизныпрограммный продукт относится к группе “В” с коэффициентом 0,7.
6.2 Расчет цены иприбыли на ПС
В современныхрыночных экономических условиях ПС выступает преимущественно в виде продукцииорганизаций, представляющей собой функционально завершенные и имеющие товарныйвид ПС ВТ, реализуемые покупателям по рыночным отпускным ценам. Все завершенныеразработки ПС ВТ являются научно-технической продукцией.
Широкое применение ВТтребует постоянного обновления и совершенствования ПС. Выбор эффективныхпроектов ПС связан с их экономической оценкой и расчетом экономическогоэффекта, который может определяться как у разработчика, так и у пользователя.
У разработчикаэкономический эффект выступает в виде чистой прибыли от реализации ПС,остающейся в распоряжении организации, а у пользователя – в виде экономиитрудовых, материальных и финансовых ресурсов, получаемой за счет:
— снижения трудоемкостирасчетов и алгоритмизации программирования и отладки программ за счетиспользования ПС в процессе разработки автоматизированных систем обработкиданных;
— сокращения расходовна оплату машинного времени и других ресурсов на отладку программ;
— снижения расходов наматериалы (магнитные ленты, магнитные диски и прочие материалы);
— ускорение ввода вэксплуатацию новых систем;
— улучшения показателейосновной деятельности в результате использования ПС.
Стоимостнаяоценка ПС у разработчиков предполагает определение размеров затрат, чтовключает следующие статьи:
— заработная платаисполнителей — основная и дополнительная;
— отчисления в фондсоциальной защиты населения;
— отчисления пообязательному страхованию от несчастных случаев на производстве ипрофессиональных заболеваний;
— расходы на материалыи комплектующие;
— расходы наспецоборудование;
— расходы на оплатумашинного времени;
— прочие прямыезатраты;
— накладные расходы.
На основании затратрассчитывается себестоимость и отпускная цена ПС.
6.2.1 Исходные данные
Таблица 6.1 – Исходныеданные для расчётовНаименование показателя Единица измерения Условные обозначения Норматив Коэффициент изменения скорости обработки информации ед.
Кск 0,7 Численность разработчиков чел.
Чр 1 Тарифная ставка 1-го разряда в организации руб.
Сзм1 77000 Тарифный коэффициент ед.
Кт 2,84 Фонд рабочего времени ч ФРВ 169.3 Коэффициент естественных потерь рабочего времени ед.
Кп 1,4 Коэффициент премирования ед.
Кпр 1 Норматив дополнительной заработной платы %
Ндз 10% Ставка отчислений в Фонд социальной защиты населения %
Нфсзн 34% Ставка отчислений по обязательному страхованию от несчастных случаев на производстве и профессиональных заболеваний %
Нбгс 1% Цена одного машино-часа руб.
Цм 2200 Норматив прочих затрат %
Нпз 12% Норматив накладных расходов %
Ннр 120% Норматив расходов на сопровождение и адаптацию %
Нрса 10% Уровень рентабельности %
Урн 24% Ставка отчислений по единому нормативу в целевые бюджетные фонды из выручки от реализации %
Нцбф 1% Ставка НДС %
Нндс 18% Норматив расходов на освоение ПС %
Нос 1% Норматив расходов на пополнение оборотных средств в связи с использованием нового ПС %
Ноб 1% Ставка налога на прибыль %
Нnр 24% Ставка местных налогов и сборов %
Нмс 3% Норматив приведения разновременных затрат ед.
Ен 0,11
6.2.2 Определениеобъема ПС
Объем ПС определяетсяпутем подбора аналогов на основании классификации типов ПС, каталога функции ПСи аналогов ПС в разрезе функций.
Таблица 6.2 –Содержание и объем функций на разрабатываемое ПС ВТФункция Объем, условных машинных команд Работа с файлами характеристик систем частиц, файлами изображений 1100 Организация ввода характеристик систем частиц пользователем 1020 Организация ввода управляющих сигналов от пользователя 700 Организация вывода графической информации в режиме реального времени 1150 Прочие расчёты, сервисные функции 700 Справка и обучение 520 Итого 5190
На основании информациио функциях разрабатываемого ПС по каталогу функций определяется объем функций.Общий объем ПС рассчитывается по формуле:
/>, (6.1)
где Vо –общий объем ПС, условных машино-команд;
Vi – объемфункций ПС, условных машино-команд;
n – общее числофункций.
/>=5190 условных машинных команд
С учетом измененияскорости обработки информации рассчитывается скорректированный объем функций:
Vo/= Vo·Кск , (6.2)
где /> – скорректированный объемПС, условных машинных команд;
/> –общий объем ПС, условных машинных команд;
Кск –коэффициент изменения скорости обработки информации.
Vo/= 5190*0,7 = 3633 условных машинных команд
6.2.3 Расчеттрудоемкости выполняемой работы
На основании общегообъема ПС определяется нормативная трудоемкость. Нормативная трудоемкостьустанавливается с учетом сложности ПС. Выделяется три группы сложности, вкоторых учтены следующие составляющие ПС; языковой интерфейса, ввод-вывод,организация данных, режим работы, операционная и техническая среда.
Общая трудоемкость ПСрассчитывается по формуле:
/> , (6.3)
где То –общая трудоемкость ПС, человеко-дней;
Тн –нормативная трудоемкость ПС, человеко-дней;
Ксл –дополнительный коэффициент сложности ПС, ед.
Уровень сложности = 1, КСЛ= 0,18, норма времени Тн = 112. Получаем:
То= 112 *0,7 *0,18 = 14 человеко-дней
6.2.4 Расчет основнойзаработной платы
Нормативнаятрудоемкость служит базой для расчета основной заработной платы.
В соответствии с “Рекомендациямипо применению “Единой тарифной сетки” рабочих и служащих народного хозяйства” итарифными разрядами и коэффициентами должностей руководителей организаций ивычислительных центров, бюджетных учреждений науки непроизводственных отраслейнародного хозяйства каждому исполнителю устанавливается разряд и тарифныйкоэффициент.
Месячная тарифнаяставка каждого исполнителя определяется путем умножения действующей месячнойтарифной ставки 1-го разряда на тарифный коэффициент, соответствующийустановленному тарифному разряду:
Сзм = Сзм1. Кт , (6.4)
где Сзм –тарифная ставка за месяц, руб.;
Сзм1– тарифная ставка 1-го разряда за месяц, руб.;
Кт –тарифный коэффициент, ед.
Сзм =77000*2,84 = 218680 руб.
Основная заработнаяплата исполнителей на конкретное ПС рассчитывается по формуле:
/> (6.5)
где Соз–основная заработная плата, руб.;
Сзд –тарифная ставка за день, руб.;
То – общаятрудоемкость ПС, человеко-дней;
Кп –коэффициент естественных потерь рабочего времени, ед.;
Кпр –коэффициент премирования, ед.
Соз = (218680/ 21,25)*14*1,4*1 = 201700 руб.
6.2.5 Расчетдополнительной заработной платы
Дополнительнаязаработная плата на конкретное ПС включает выплаты, предусмотренныезаконодательством о труде (оплата отпусков, льготных часов, времени выполнениягосударственных обязанностей и других выплат, не связанных с основнойдеятельностью исполнителей), и определяется по нормативу в процентах к основнойзаработной плате:
/>, (6.6)
где Сдз –дополнительная заработная плата на конкретное ПС, руб.;
Ндз –норматив дополнительной заработной платы, %.
Cдз=201700 * 0,1 = 20170 руб.
6.2.6 Расчет отчисленийв Фонд социальной защиты населения
Отчисления в фондсоциальной защиты населения определяются в соответствии с действующимизаконодательными актами по нормативу в процентном отношении к фонду основной идополнительной зарплаты исполнителей, определенной по нормативу, установленномув целом по организации:
/>, (6.7)
где Сфсзн –сумма отчислений в Фонд социальной защиты населения, руб.;
Нфсзн –норматив отчислений в Фонд социальной защиты населения, %.
Cфсзн= (201700 + 20170) * 0,34 = 75436 руб.
6.2.7 Расчет отчисленийпо обязательному страхованию от несчастных случаев на производстве ипрофессиональных заболеваний
Отчисления пообязательному страхованию от несчастных случаев на производстве ипрофессиональных заболеваний рассчитываются по формуле:
/>, (6.8)
где Сбгс –сумма отчислений по обязательному страхованию от несчастных случаев напроизводстве и профессиональных заболеваний, руб.;
Нбгс –норматив отчислений по обязательному страхованию от несчастных случаев напроизводстве и профессиональных заболеваний, %.
Сбгс = (201700+ 20170)*0,01 = 2219 руб.
6.2.8 Расчет расходовна материалы и комплектующие
По статье “Материалы”отражаются расходы на магнитные носители, бумагу, красящие ленты и другиематериалы, необходимые для разработки ПС. Нормы расхода материалов в суммарномвыражении определяются в расчете на 100 строк исходного кода. Сумма затратматериалов рассчитывается по формуле:
/>, (6.9)
где См –сумма расходов на материалы, руб.;
Нм – нормарасхода материалов в расчете на 100 строк исходного кода ПС, руб.
См = 380*0,7*3633/100= 9664 руб.
6.2.9 Расчет расходовна оплату машинного времени
Расходы по статье “Машинноевремя” включают оплату машинного времени, необходимого для разработки и отладкиПС, которое определяется по нормативам (в машино-часах) на 100 строк исходногокода машинного времени в зависимости от характера решаемых задач и типа ПК:
/> , (6.10)
где Смв –сумма расходов на оплату машинного времени, руб.;
Цм – ценаодного машино-часа, руб.;
Нмв –норматив расхода машинного времени на отладку 100 строк исходного кода,машино-часов.
Смв = 2200*3633/100*12*0,6= 575467 руб.
6.2.10 Расчет прочихпрямых затрат
Расходы на конкретноеПС включают затраты на приобретение и подготовку специальной научно-техническойинформации и специальной литературы. Определяются по нормативу в процентах косновной заработной плате:
/> , (6.11)
где Спз –сумма прочих затрат, руб.;
Нпз –норматив прочих затрат в целом по организации, %.
Спз = 201700*12/100= 24204 руб.
6.2.11 Расчет накладныхрасходов
Данные затраты, связанныес необходимостью содержания аппарата управления, а также с расходами наобщехозяйственные нужды, рассчитываются для конкретного ПС по нормативу впроцентном отношении к основной заработной плате исполнителей:
/> , (6.12)
где Снр –сумма накладных расходов, руб.;
Ннр –норматив накладных расходов в целом по организации, %.
6.2.12 Расчет суммырасходов на разработку ПС ВТ
Общая сумма расходов наПС рассчитывается по формуле:
/>, (6.13)
где Ср –сумма расходов на разработку ПС ВТ, руб.;
Ср = 201700 +20170 + 75436 + 2219 + 9664 + 0 + 575467 + 24204 + 242040 = 1150900 руб.
6.2.13 Расчет расходовна сопровождение и адаптацию
Кроме того,организация-разработчик осуществляет затраты на сопровождение и адаптацию ПС,которые определяются по нормативу:
/>, (6.14)
где Срса –сумма расходов на сопровождение и адаптацию ПС ВТ, руб.;
Нрса –норматив расходов на сопровождение и адаптацию, %.
Срса = 1150900* 10/100 = 115090 руб.
6.2.14 Расчет полнойсебестоимости разработки ПС ВТ
Общая сумма расходов наразработку (с затратами на сопровождение и адаптацию) – полная себестоимость ПС– определяется по формуле:
/>,(6.15)
Сп = 1150900+ 115090 = 1265990 руб.
6.2.15 Определениеотпускной цены на ПС ВТ
Отпускнаяцена определяется на основании цены разработчика, которая формируется на основепоказателя рентабельности продукции. Рентабельность и прибыль по создаваемомуПС определяются исходя из результатов анализа рыночных условий, переговоров сзаказчиком (потребителем) и согласования с ним отпускной цены, включающейдополнительно налог на добавленную стоимость и отчисления в целевые бюджетныефонды из выручки от реализации продукции.
Прибыльрассчитывается по формуле:
/> , (6.16)
где Ппс –прибыль от реализации ПС, руб.;
Урп –уровень рентабельности ПС, %;
Ппс = 1265990* 24/100 = 303838 руб.
Прогнозируемая ценаразработчика ПС без налогов:
Цп = Сп+ Ппс, (6.17)
где Цп –прогнозируемая цена разработчика ПС, руб.;
Цп = 1265990+ 303838 = 1569828 руб.
Сумма отчислений вцелевые бюджетные фонды из выручки от реализации продукции единым платежом:
/> , (6.18)
где Сцбф –сумма отчислений в целевые бюджетные фонды из выручки от реализации продукцииединым платежом, руб.;
Нцбф –ставка отчислений в целевые бюджетные фонды из выручки от реализации продукцииединым платежом, %.
Сцбф = 1569828* 1/(100-1) = 15857 руб.
Сумма налога надобавленную стоимость:
/> , (6.19)
где НДС – сумма налогана добавленную стоимость, руб.;
Нндс –ставка НДС, %.
НДС = (1569828 + 15857) * 18/100 = 285423руб.
Прогнозируемаяотпускная цена:
/>, (6.20)
где Цо –прогнозируемая отпускная цена, руб.
Цо = 1569828+ 15857 + 285423 = 1871108 руб.
6.3 Расчетэкономического эффекта от применения ПС у пользователя
Создаваемые программныесредства могут предназначаться как для совершенно новых, ранее не решавшихсяили решавшихся ручным способом задач, так и для традиционных задач, решаемых спомощью программных средств, которые можно совершенствовать.
В результате применениянового ПС пользователь может понести значительные капитальные затраты наприобретение и освоение ПС, доукомплектования ЭВМ новыми техническимисредствами и пополнение оборотных средств. Однако, если приобретенное ПС будетв достаточной степени эффективнее базового, то дополнительные капитальныезатраты быстро окупятся. Эффект может быть достигнут за счет сокращения объемаПС (уменьшения количества машинных команд, количества строк и т.д.), снижениетрудоемкости подготовки данных, обработки информации, анализа результатов,уменьшения расходов машинного времени и материалов.
Для определенияэкономического эффекта от использования нового ПС у потребителя необходимосравнить расходы по всем основным статьям затрат на эксплуатацию нового ПС(расходы на заработную плату с начислениями, материалы, машинное время) срасходами по соответствующим статьям базового варианта. При этом за базовыйвариант следует принимать аналогичное программное средство, используемое вдействующей автоматизированной системе. При сравнении базового и новоговариантов ПС в качестве экономического эффекта будет выступать общая экономиявсех видов ресурсов относительно базового варианта. При этом создание нового ПСокажется экономически целесообразным лишь в том случае, если все капитальныезатраты окупятся за счет получаемой экономии в ближайшие 1–2 года.
6.3.1 Исходные данные
Таблица 6.3 – Исходныеданные для сравнения вариантовНаименование показателей Обозначения Единицы измерения Значение показателя Наименование источника информации в базовом варианте в новом варианте Средняя трудоемкость работ в расчете на 100 строк кода
Тс1
Тс2 человеко-дней с на 100 строк кода 0,96 0,92 По данным пользователя Средний расход машинного времени в расчете на 100 строк кода
Нмв1
Нмв2 машино-час на 100 строк кода 7,7 7,2 По данным пользователя
Средний расход материалов в расчете на
100 строк кода
См1
См2 руб. на 100 строк кода 341 266 По данным пользователя
Объем работ взависимости от функциональной группы и назначения ПС определяется по формуле:
А = Vо'∙ Кпс , (6.21)
где Vо'– скорректированный объем ПС, условных машино-команд;
Кпс –коэффициент применения ПС, ед.
Таким образом, A=3633 * 0,7 = 2543 условных машинных команд
6.3.2 Расчеткапитальных затрат заказчика ПС
Общие капитальныевложения заказчика (потребителя), связанные с приобретением, внедрением ииспользованием ПС, рассчитываются по формуле:
Ко = Кпр+ Кос + Коб, (6.22)
где Кпр –затраты пользователя на приобретение ПС по отпускной цене разработчика с учетомстоимости услуг по эксплуатации и сопровождению, руб.;
Кос –затраты пользователя на освоение ПС, руб.;
Коб –затраты на пополнение оборотных средств в связи с использованием нового ПС,руб.
Затраты на освоение ПСи на пополнение оборотных средств рекомендуется рассчитывать по формулам:
Кос = Кпр∙ Нос , (6.23)
Коб = Кпр∙ Ноб , (6.24)
Кпр = Цо= 1871108
Кос = 1871108* 0,01 = 18711 руб.
Коб = 1871108* 0,01 = 18711 руб.
Ко = 1871108+ 18711 + 18711 = 1908530 руб.
6.3.3 Расчет экономииосновных видов ресурсов в связи с использованием нового ПС
Экономия затрат назаработную плату при использовании нового ПС в расчете на объем выполненныхработ:
Эоз = Эоз'∙ А, (6.25)
где Эоз –экономия затрат на заработную плату при решении задач с использованием новогоПС, руб.;
Эоз' –экономия затрат на заработную плату при решении задач с использованием новогоПС в расчете на 100 КБ, руб.;
А – объем выполненныхработ с использованием нового ПС, 100 КБ.
Экономия затрат назаработную плату в расчете на 100 КБ:
/>, (6.26)
где Сзм –среднемесячная заработная плата одного программиста, руб.;
Тс1, Тс2– трудоемкость работ в расчете на 100 строк кода при базовом и новом вариантесоответственно, человеко-часов;
Тч –количество часов работы в день, ч;
ФРВ – фонд рабочеговремени за месяц, ч.
Тс2 = 0,3*112*100/3633= 0,92 человеко-дней
Эоз’ =218680 * 0,04 / 169,3 = 52 руб.
Эоз = 52 * 2543= 131389 руб.
При определениитрудоемкости, связанной с использованием программы рекомендуетсяориентироваться на показатель равный 30-50% от трудоемкости разработки в часах.
Экономия начислений назаработную плату при использовании нового ПС в расчете на объем выполненныхработ:
Энач = Эоз∙ Кнач , (6.27)
где Энач –экономия начислений на заработную плату при решении задач с использованиемнового ПС, руб.;
Кнач –коэффициент начислений на заработную плату, ед.
/>, (6.28)
Кнач = (34 +1)/100 = 0,35 ед.
Энач = 131389* 0,35 = 45986 руб.
Экономия затрат наоплату машинного времени в расчете на выполненный объем работ в результатеприменения нового ПС:
/>, (6.29)
где Эмв –экономия затрат на оплату машинного времени при решении задач с использованиемнового ПС, руб.;
/> –экономия затрат на оплату машинного времени при решении задач с использованиемнового ПС в расчете на 100 КБ, руб.
Экономия затрат наоплату машинного времени в расчете на 100 КБ:
/>, (6.30)
где Нмв1, Нмв2– средний расход машинного времени в расчете на 100 КБ при применении базовогои нового варианта ПС соответственно, машино-часов.
Эмв’ = 2200* 0,5 = 1100 руб.
Эмв = 1100 *2543 = 2797300 руб.
Экономия затрат наматериалы при использовании нового ПС в расчете на объем выполненных работ:
/>, (6.31)
где Эм –экономия затрат на материалы при использовании нового ПС, руб.;
Эм' –экономия затрат на материалы в расчете на 100 КБ при использовании нового ПС,руб.:
/>, (6.32)
где См1, См2– средний расход материалов у пользователя в расчете на 100 КБ прииспользовании базового и нового варианта ПС соответственно, руб.
Эм’ =341-266=75 руб.
Эм =75*2543= 190725 руб.
Общая годовая экономиятекущих затрат, связанных с использованием нового ПС:
/>, (6.33)
Эо = 131389 + 45986 + 2797300 + 190725 = 3165400 руб.
6.3.4 Расчёт экономического эффекта
Внедрение нового ПСпозволит пользователю сэкономить на текущих затратах, т.е. практически получитьна эту сумму дополнительную прибыль. Для пользователя в качестве экономическогоэффекта выступает лишь чистая прибыль – дополнительная прибыль, остающаяся вего распоряжении (ΔПч), которая определяются по формуле:
/>, (6.34)
где ∆Пч –прирост чистой прибыли, руб.;
Нмс – ставкаместных налогов и сборов, %.
/>, (6.35)
где ∆П – приростприбыли, руб.;
Нп – ставканалога на прибыль, %.
/>=3165400 – 3165400 * 24/100 = 2405704 руб.
/>=2405704 – 2405704 * 3/100 = 2333533 руб.
В процессеиспользования нового ПС чистая прибыль в конечном итоге возмещает капитальныезатраты. Однако, полученные при этом суммы результатов (прибыли) и затрат(капитальных вложений) по годам приводят к единому времени – расчетному году(за расчетный год принят 2008 год) путем умножения результатов и затрат закаждый год на коэффициент привидения (ALFAt), который рассчитываетсяпо формуле:
/>, (6.36)
где Ен – нормативпривидения разновременных затрат и результатов;
tp –расчетный год, tp = 1;
t – номер года,результаты и затраты которого приводятся к расчетному (2008-1, 2009-2, 2010-3,2011-4).
Норматив приведенияразновременных затрат и результатов (Ен) для программных средств ВТв существующей практике принимается равным 0,12. При таком нормативекоэффициентам приведения (ALFAt) по годам будут соответствоватьследующие значения:
ALPHA1= (1+0,15) 1-1 = 1
ALPHA2=(1+0,15) 1-2 = 0,870
ALPHA3=(1+0,15) 1-3 = 0,756
ALPHA4=(1+0,15) 1-4 = 0,658
Данные расчетаэкономического эффекта сведем в таблицу:
Таблица 6.4 — Расчетэкономического эффекта от использования нового ПСПоказатели
Ед.
измерения Методика расчета 2008 2009 2010 2011 Результаты: Прирост прибыли за счет экономии затрат руб.
∆ Пч 2333533 2333533 2333533 2333533 Сумма прибыли с учетом фактора времени руб.
∆ Пч ∙ ALFAt 2333533 2030174 1764151 1535465 Затраты: Затраты на приобретение ПС руб.
Кпр 1871108 - - - Затраты на освоение ПС руб.
Кос 18711 - - - Затраты на доукомплектование ВТ техническими средствами руб.
Ктс - - - - Затраты на пополнение оборотных средств руб.
Коб 18711 18711 18711 18711 Сумма затрат руб.
Ко 1908530 18711 18711 18711 Сумма затрат с учетом фактора времени руб.
Ко ∙ ALFAt 1908530 16279 14146 12312 Экономический эффект руб.
∆ Пч ∙ ALFAt -Ко ∙ ALFAt 425003 2013895 1750005 1523153 Экономический эффект с нарастающим итогом руб.
425003 2438898 4188903 5712056 Коэффициент приведения ед.
ALFAt 1 0,870 0,756 0,658
6.4 Результаты оценкиэкономической целесообразности
В данном разделе быларассчитана отпускная цена программного средства, которая составила 1871108руб. Затраты потребителя, связанные с приобретением, освоением программногосредства, а также пополнением оборотных средств – 1951267 руб. Прирост прибылиза счёт экономии начислений на заработную плату, оплаты машинного времени иматериалов в каждый из расчётных лет составил соответственно 2333533 руб.,2030174 руб., 1764151 руб. и 1535465 руб. Затраты потребителя окупились уже впервый год, при этом получился положительный экономический эффект в размере 425003руб. Экономический эффект за 4 года использования ПС составит 5712056 руб. Всёэто даёт возможность говорить о том, что создание и внедрение ПС целесообразно.
Заключение
Впредставленном дипломном проекте разработан графический редактор эффектовчастиц “EasyParticles”.
Приразработке были использованы самые современные подходы к проектированиюпрограммного обеспечения. Программное обеспечение разработано с учетом простотыбудущей модификации.
Программаимеет удобный пользовательский интерфейс, отвечающий современным требованиям.Она может использоваться на различных компьютерах с различной конфигурацией ине требует много ресурсов. Пользовательский интерфейс программы рассчитан наминимальные навыки работы с компьютером.
Входе выполнения поставленной задачи реализованы все основные функциипрограммного средства. Все предъявляемые к программе требования были выполнены.Отладка и тестирование программы проведены успешно.
Проведенотехнико-экономическое обоснование внедрения спроектированной системы.Полученный экономический эффект позволяет окупить затраты пользователя назакупку, установку ПС, обучение сотрудников его использованию и остальные.Следовательно, разработка является экономически целесообразной.
Цель,поставленная перед автором работы, была выполнена в полной мере. Проект выполненв соответствие с ГОСТами и требованиями, предъявляемыми к техническойдокументации.
Какуже было сказано, разработанная версия приложения является первой реализацией,наиболее общей, позволяющей использовать лишь самые основные величины иоперировать сильно ограниченным множеством настроек и характеристик.
Планируемоебудущее расширение должно коснуться, в первую очередь, пользовательскогоинтерфейса, а также задаваемых параметров частиц и эмиттеров. В целях большегоудобства использования редактора, в него планируется внести изменения,связанные со способами задания скорости частиц и гравитации, действующей наних. Возможно, будет введены параметры дисперсии гравитации, или иныепараметры, задающие изменение значений гравитации. Сами значения скорости игравитации планируется вводить посредством векторов.
Необходимоизменить способы задания изменения цвета частиц (через визуальный цветовой элементуправления), ввести возможность использования дополнительных ключей цвета, сучётом длительности перехода частицы от одного цвета к другому.
Аналогичныепараметры-ключи (и визуальные элементы управления, соответствующие им) будутвведены для размеров частиц.
Дляразмеров, цвета, задержки генерации частиц планируется ввести параметрыдисперсии.
Некоторыеизменения претерпит и оконная система приложения. В ней будут преобладатьперетаскиваемые присоединяемые панели. Станет возможным изменение размеров окнавывода, а также использование полноэкранного режима при просмотре эффектов.
Средипрочих возможных изменений можно отметить запуск в окне просмотра и встраиваниеэффектов частиц в файлы видео, а также расширенные программные интерфейсы дляразработчиков компьютерных игр и иных графических приложений.
Перечисленные изменениядолжны повысить интерес к программному средству и его полезность для разныхгрупп пользователей.
Список использованныхисточников
1) Бьёрн Страуструп Дизайн и эволюцияязыка C++ – М.: ДМК пресс,2006. – 448с.
2) Ефремова О.С. Требования охраны трудапри работе на персональных электронно-вычислительных машинах (ПК) – М.:Альфа-пресс, 2005. – 150с.
4) Санитарные нормы для образовательныхучреждений. – 5-е изд., доп. – М.: Образование в документах, 2002. – 200с.
5) Замбржицкий О.Н. Гигиеническая оценкаестественного и искусственного освещения помещений. – Мн.: БГМУ, 2005. – 18 с.
6) СанПиН N 9-131 РБ 2000 Гигиеническиетребования к видеодисплейным терминалам (ВДТ), электронно-вычислительным машинам(ЭВМ) и организации работы
7) Косилина Н.И., Колтановского А.П.Производственная гимнастика для работников умственного труда – М.: Физкультураи спорт, 1983.
8) Кляуззе В.П. Безопасность &компьютер. – Мн.: В.П.Кляуззе, 2001. – 155с.
Приложение А
(обязательное)
Текст программногомодуля обработки частиц
//ParticleSystemChain.cpp(очередьэмиттеров)
#include«ParticleSystemChain.h»
#include«PSOutputFrame.h»//just for using canvas to get current reflectingmode ang zoom
#defineBLEND_SRC «blend_src»
#defineBLEND_DST «blend_dst»
#defineITEM_SELECTED «item_selected»
#definePSBOUND_SELECTED_COLOR wxColour(200, 200, 200, 255)
#definePSBOUNS_CHOOSED_COLOR wxColour(70, 70, 70, 255)
#definePSBOUND_COLOR wxColour(50, 50, 50, 255)
#defineMIN_RUN_PSCHAIN_ITEM_DIMENSION 20
ParticleSystemChain*ParticleSystemChain::singletonChain = NULL;
ParticleSystemChain*ParticleSystemChain::Master()
{
if(!singletonChain)
singletonChain= new ParticleSystemChain();
returnsingletonChain;
}
voidParticleSystemChain::CleanSingleton()
{
if(singletonChain)
{
deletesingletonChain;
singletonChain= NULL;
}
}
intParticleSystemChain::AddSystem()
{
ParticleSystem*ps = new ParticleSystem();
all_ps.push_back(ps);
if(workMode!= ParticleSystemChainWorkMode_STATIC)
ps->start();
intnew_ps_layer = (int)all_ps.size() — 1;
if(selectedSystemLayer
selectedSystemLayer= new_ps_layer;
returnnew_ps_layer;
}
boolParticleSystemChain::RemoveSystemAtLayer(int layer)
{
if((layer = (int)all_ps.size()) )
returnfalse;
deleteall_ps.at(layer);
all_ps.erase(all_ps.begin()+ layer);
if(layer== choosedSystemLayer)
choosedSystemLayer= -1;
if(all_ps.size()== 0)
selectedSystemLayer= -1;
else
if(selectedSystemLayer>= layer && selectedSystemLayer > 0)
selectedSystemLayer--;
returntrue;
}
voidParticleSystemChain::RemoveAll()
{
vector::iteratoriter = all_ps.begin();
while(iter!= all_ps.end())
{
delete((ParticleSystem*)*iter);
++iter;
}
all_ps.clear();
selectedSystemLayer= choosedSystemLayer = -1;
}
voidParticleSystemChain::MoveSystem(int from, int to)
{
intnumof_systems = (int)all_ps.size();
if((from == to) || (from = numof_systems) || (to = numof_systems) )
return;
ParticleSystem*tmp_ps_ptr = all_ps.at(from);
all_ps.erase(all_ps.begin()+ from);
all_ps.insert(all_ps.begin()+ to, tmp_ps_ptr);
}
voidParticleSystemChain::CopySystemsData(int layer_from, int layer_to)
{
intnumof_systems = (int)all_ps.size();
if(layer_from== layer_to || layer_from = numof_systems || layer_to= numof_systems )
return;
all_ps.at(layer_to)->copyDataFromParticleSystem(all_ps.at(layer_from));
}
boolParticleSystemChain::Save(TiXmlElement* root) const
{
TiXmlElementtmp(«BLENDING»);
TiXmlElement*caption = (TiXmlElement*)root->InsertEndChild(tmp);
if(!caption)
returnfalse;
caption->SetAttribute(BLEND_SRC,blendModeSrc);
caption->SetAttribute(BLEND_DST,blendModeDst);
returnsaveSystems(root);
}
boolParticleSystemChain::Load(TiXmlElement *root)
{
TiXmlElement*blending_attrs_ptr = (TiXmlElement*)root->FirstChild(«BLENDING»);
if(!blending_attrs_ptr)//oldversion file (1.0), just set defaults
{
blendModeSrc= GL_ONE;
blendModeDst= GL_ONE_MINUS_SRC_ALPHA;
}
else
{
blending_attrs_ptr->Attribute(BLEND_SRC,&blendModeSrc);
blending_attrs_ptr->Attribute(BLEND_DST,&blendModeDst);
}
returnloadSystems(root);
}
ParticleSystemOutputCoordCharacterParticleSystemChain::AnalyseOutputCoords(MYPoint2D point) const
{
ParticleSystemOutputCoordCharacterres;
res.psLayer= -1;
res.isLeft= res.isRight = res.isTop = res.isBottom = false;
//firstfind selecting system layer
vector::const_iteratoriter = all_ps.end();
vector::const_iteratorbegin_iter = all_ps.begin();
size_ti = all_ps.size();
wxRectsystem_rect, tmp_rect;
boolchain_is_run = (workMode != ParticleSystemChainWorkMode_STATIC);
while(iter!= begin_iter)
{
--iter,--i;
wxRecttmp_rect;
MYPoint2Dappear_box_position = MYPoint2DMake((*iter)->getX(), (*iter)->getY());
MYSize2Dappear_box_size = (*iter)->getAppearBoxSize();
if(chain_is_run)
{
tmp_rect= wxRect(appear_box_position.x, appear_box_position.y, appear_box_size.width,appear_box_size.height);
if(tmp_rect.GetWidth()
{
intdiff = MIN_RUN_PSCHAIN_ITEM_DIMENSION — tmp_rect.GetWidth();
tmp_rect.SetX(tmp_rect.GetX()- diff / 2);
tmp_rect.SetWidth(MIN_RUN_PSCHAIN_ITEM_DIMENSION);
}
if(tmp_rect.GetHeight()
{
intdiff = MIN_RUN_PSCHAIN_ITEM_DIMENSION — tmp_rect.GetHeight();
tmp_rect.SetY(tmp_rect.GetY()- diff / 2);
tmp_rect.SetHeight(MIN_RUN_PSCHAIN_ITEM_DIMENSION);
}
}
else
tmp_rect= wxRect(appear_box_position.x — BOUND_DIMENSION, appear_box_position.y — BOUND_DIMENSION,
appear_box_size.width+ BOUND_DIMENSION * 2, appear_box_size.height + BOUND_DIMENSION * 2);
if(point.x>= tmp_rect.x && point.x
point.y>= tmp_rect.y && point.y
{
res.psLayer= (int)i;
system_rect= tmp_rect;
break;
}
}
if(res.psLayer == -1/*no selected ps*/ || chain_is_run )
returnres;
//selectingsystem has been finded, and — maybe we touched on some ps'sbottom(-s)
if((point.x >= system_rect.x) && (point.x
res.isLeft= true;
if((point.x =system_rect.x + system_rect.width — BOUND_DIMENSION) )
res.isRight= true;
if((point.y >= system_rect.y) && (point.y
res.isTop= true;
if((point.y =system_rect.y + system_rect.height — BOUND_DIMENSION) )
res.isBottom= true;
returnres;
}
voidParticleSystemChain::ChooseSystemAtLayer(int layer)
{
if((layer = (int)all_ps.size()) )
choosedSystemLayer= -1;
else
choosedSystemLayer= layer;
}
intParticleSystemChain::GetChoosedSystemLayer() const
{
returnchoosedSystemLayer;
}
voidParticleSystemChain::SelectSystemAtLayer(int layer)
{
if((layer = (int)all_ps.size()) )
selectedSystemLayer= -1;
else
selectedSystemLayer= layer;
}
intParticleSystemChain::GetSelectedSystemLayer() const
{
returnselectedSystemLayer;
}
ParticleSystemChainWorkModeParticleSystemChain::GetWorkMode() const
{
returnworkMode;
}
voidParticleSystemChain::SetWorkMode(ParticleSystemChainWorkMode mode)
{
vector::iteratorbegin_iter = all_ps.begin();
vector::iteratorend_iter = all_ps.end();
vector::iteratoriter = begin_iter;
if(mode== ParticleSystemChainWorkMode_PLAYBACK || mode ==ParticleSystemChainWorkMode_PLAYBACK_LOOP)
{
while(iter!= end_iter)
{
(*iter)->start();
++iter;
}
timer.reset();
}
else//if(mode== ParticleSystemChainWorkMode_STATIC)
{
while(iter!= end_iter)
{
(*iter)->stopExtra();
++iter;
}
}
workMode= mode;
}
voidParticleSystemChain::CallbackSystems()
{
if(workMode== ParticleSystemChainWorkMode_STATIC)
return;
doublesec_interval = timer.getMilliseconds() / 1000.0;
timer.reset();
vector::iteratoriter = all_ps.begin();
boolchain_is_run = false;
while(iter!= all_ps.end())
{
(*iter)->callback(sec_interval);
if(!(*iter)->isFinished())
chain_is_run= true;
++iter;
}
if(chain_is_run)
return;
//!chain_is_run
if(workMode== ParticleSystemChainWorkMode_PLAYBACK)
SetWorkMode(ParticleSystemChainWorkMode_STATIC);
else//if(workMode == ParticleSystemChainWorkMode_PLAYBACK_LOOP)
SetWorkMode(ParticleSystemChainWorkMode_PLAYBACK_LOOP);//justrestart
}
voidParticleSystemChain::DrawSystems()
{
vector::iteratoriter = all_ps.begin();
if(workMode!= ParticleSystemChainWorkMode_STATIC)
{
glEnable(GL_BLEND);
glBlendFunc(blendModeSrc,blendModeDst);
while(iter!= all_ps.end())
{
(*iter)->draw();
++iter;
}
glDisable(GL_BLEND);
}
else
{
inti = 0;
while(iter!= all_ps.end())
{
ParticleSystem*curr_ps = (*iter);
if(i== selectedSystemLayer)
curr_ps->setBoundColor(PSBOUND_SELECTED_COLOR);
elseif(i == choosedSystemLayer)
curr_ps->setBoundColor(PSBOUNS_CHOOSED_COLOR);
else
curr_ps->setBoundColor(PSBOUND_COLOR);
curr_ps->drawBound();
++iter,++i;
}
}
}
intParticleSystemChain::GetBlendModeSrc() const
{
returnblendModeSrc;
}
intParticleSystemChain::GetBlendModeDst() const
{
returnblendModeDst;
}
voidParticleSystemChain::SetBlendModeSrc(int mode)
{
blendModeSrc= mode;
}
voidParticleSystemChain::SetBlendModeDst(int mode)
{
blendModeDst= mode;
}
ParticleSystem*ParticleSystemChain::GetSystemAtLayer(int layer)
{
if(layer = (int)all_ps.size() )
returnNULL;
returnall_ps.at(layer);
}
MYRectParticleSystemChain::GetInitialSystemsRect(unsigned int *systems_counter)const//systems bound rect on gl
{
*systems_counter= (unsigned int)all_ps.size();
doublemin_x = 0.0;
doublemin_y = 0.0;
doublemax_x = 0.0;
doublemax_y = 0.0;
vector::const_iteratorbegin_iter = all_ps.begin();
vector::const_iteratorend_iter = all_ps.end();
vector::const_iteratoriter = begin_iter;
while(iter!= end_iter)
{
boolthereis_begin_ps = (iter == begin_iter);
if(thereis_begin_ps|| min_x > (*iter)->data.initialX)
min_x= (*iter)->data.initialX;
if(thereis_begin_ps|| min_y > (*iter)->data.initialY)
min_y= (*iter)->data.initialY;
doublenew_max = (*iter)->data.initialX + (*iter)->data.pAppearBoxSize.width;
if(thereis_begin_ps|| max_x
max_x= new_max;
new_max= (*iter)->data.initialY + (*iter)->data.pAppearBoxSize.height;
if(thereis_begin_ps|| max_y
max_y= new_max;
++iter;
}
MYPoint2Dpos = MYPoint2DMake(min_x, min_y);
MYSize2Dsz = MYSize2DMake(max_x — min_x, max_y — min_y);
return(MYRectMake(pos,sz));
}
intParticleSystemChain::GetNumofSystems() const
{
return(int)all_ps.size();
}
//internals
ParticleSystemChain::ParticleSystemChain()
{
workMode= DEFAULT_PARTICLE_SYSTEM_CHAIN_WORK_MODE;
blendModeSrc= GL_ONE;
blendModeDst= GL_ONE_MINUS_SRC_ALPHA;
selectedSystemLayer= choosedSystemLayer = -1;
}
ParticleSystemChain::~ParticleSystemChain()
{
RemoveAll();
}
boolParticleSystemChain::saveSystems(TiXmlElement* root) const
{
TiXmlElementtmp(«SYSTEMS_DATA»);
TiXmlElement*sys_data = (TiXmlElement*)root->InsertEndChild(tmp);
if(!sys_data)
returnfalse;
sys_data->SetAttribute(ITEM_SELECTED,selectedSystemLayer);
if(all_ps.size()== 0)
returntrue;
vector::const_iteratoriter = all_ps.end();
do
{
--iter;
if(!(*iter)->save(root))
returnfalse;
}
while(iter!= all_ps.begin());
returntrue;
}
boolParticleSystemChain::loadSystems(TiXmlElement* root)
{
TiXmlElement*systems_data_ptr =(TiXmlElement*)root->FirstChild(«SYSTEMS_DATA»);
intselected_system_layer = -1;
if(systems_data_ptr)//newformat file (ver. above 1.0)
systems_data_ptr->Attribute(ITEM_SELECTED,&selected_system_layer);
vectortmp_all_ps;
ParticleSystem*tmp_ps_ptr = new ParticleSystem();
while(boolis_success = tmp_ps_ptr->load(root))
{
tmp_all_ps.insert(tmp_all_ps.begin(),tmp_ps_ptr);
tmp_ps_ptr= new ParticleSystem();
}
deletetmp_ps_ptr;
if(tmp_all_ps.size()> 0 && selected_system_layer
selectedSystemLayer= 0;
else
selectedSystemLayer= selected_system_layer;
//removeall old-created and add new
vector::iteratoriter = all_ps.begin();
while(iter!= all_ps.end())
{
delete((ParticleSystem*)*iter);
++iter;
}
all_ps.clear();
tmp_all_ps.swap(all_ps);
workMode= ParticleSystemChainWorkMode_STATIC;
returntrue;
}
//ParticleSystem.cpp(эмиттер)
#include«ParticleSystem.h»
#include«MYSpinCtrld.h»
#definePS_BOUNDED_RECT_COLOR wxColour(150, 150, 150, 255)
//XMLelement's attributes of PSs
#defineTEXTURE_ATTR «texture_file_name»
#defineLIFE_TIME_ATTR «life_time»
#defineAPPEAR_DELAY_ATTR «appear_delay»
#definePARTICLE_SPEED_X_ATTR «particle_speed_x»
#definePARTICLE_SPEED_Y_ATTR «particle_speed_y»
#defineGRAVITY_X_ATTR «gravity_x»
#defineGRAVITY_Y_ATTR «gravity_y»
#defineMAX_COUNT_ATTR «max_count»
#defineSTART_COUNT_ATTR «start_count»
#defineAPPEAR_BOX_W_ATTR «appear_box_w»
#defineAPPEAR_BOX_H_ATTR «appear_box_h»
#defineRED_BEGIN_ATTR «red_begin»
#defineRED_END_ATTR «red_end»
#defineGREEN_BEGIN_ATTR «green_begin»
#defineGREEN_END_ATTR «green_end»
#defineBLUE_BEGIN_ATTR «blue_begin»
#defineBLUE_END_ATTR «blue_end»
#defineALPHA_BEGIN_ATTR «alpha_begin»
#defineALPHA_END_ATTR «alpha_end»
#defineSCALE_BEGIN_W_ATTR «scale_begin_w»
#defineSCALE_BEGIN_H_ATTR «scale_begin_h»
#defineSCALE_END_W_ATTR «scale_end_w»
#defineSCALE_END_H_ATTR «scale_end_h»
#defineDISPERSION_X_ATTR «dispersion_x»
#defineDISPERSION_Y_ATTR «dispersion_y»
#definePS_X_ATTR «ps_x»
#definePS_Y_ATTR «ps_y»
#definePS_SPEED_X_ATTR «ps_speed_x»
#definePS_SPEED_Y_ATTR «ps_speed_y»
#defineSTART_DELAY_ATTR «start_delay»
#defineSTOP_DELAY_ATTR «stop_delay»
#defineROTATE_ATTR «rotate»
//ctors,destructors, ...
ParticleSystem::ParticleSystem()
{
data.pLifeTime=1.0;
data.pMaxCount= EXPL_MAX;
data.pCountOnStart= 1;
data.pGravityX= data.pGravityY = 0.0;
//p.speed,dispersion page
data.pMoveSpeedX= 0.0;
data.pMoveSpeedY= 0.0;
data.pKFDispersionX= 0.0;
data.pKFDispersionY= 0.0;
//p.scalepage
data.pKFScaleBeginW= 1.0;
data.pKFScaleBeginH= 1.0;
data.pKFScaleEndW= 1.0;
data.pKFScaleEndH= 1.0;
//p.colorpage
data.pRedBegin= 1.0;
data.pGreenBegin= 1.0;
data.pBlueBegin= 1.0;
data.pAlphaBegin= 1.0;
data.pRedEnd= 1.0;
data.pGreenEnd= 1.0;
data.pBlueEnd= 1.0;
data.pAlphaEnd= 1.0;
//rotate
data.pAngleRotate= 0.0;
//startin, stop in page
data.startDelay= 0.0;
data.stopDelay= 1800.0;
data.pAppearDelay= 0.0;
//PSsettings page
MYSize2Dsz = {100.0,100.0};
data.pAppearBoxSize= sz;
data.speedChangeX= 0;
data.speedChangeY= 0;
data.initialX= currentX = BOUND_DIMENSION;
data.initialY= currentY = BOUND_DIMENSION;
boundedRectColor= PS_BOUNDED_RECT_COLOR;
particleTexPtr= NULL;
setDefaultParticleTex();
isRunb= false;
isFinishedb= false;
viewMatrixCache= (GLdouble*)malloc(sizeof(GLdouble) * 16);
assert(viewMatrixCache!= NULL);
}
ParticleSystem::~ParticleSystem()
{
free(viewMatrixCache);
if(particleTexPtr)
deleteparticleTexPtr;
}
intParticleSystem::setParticleTex(const wxString &texture_path)
{
MYTexture*tmp_tex = new MYTexture(texture_path);
intres = tmp_tex->getState();
if(res!= TEX_OK)
{
deletetmp_tex;
returnres;
}
if(particleTexPtr)
deleteparticleTexPtr;
particleTexPtr= tmp_tex;
data.particleTexFileName= texture_path;
MYTexCoordPoint*ptrTex = texCoord;
for(inti = 0; i
{
ptrTex->x= 0.0; ptrTex->y = 0.0;
ptrTex++;
ptrTex->x= particleTexPtr->getMaxS(); ptrTex->y = 0.0;
ptrTex++;
ptrTex->x= particleTexPtr->getMaxS(); ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
ptrTex->x= 0.0; ptrTex->y = 0.0;
ptrTex++;
ptrTex->x= particleTexPtr->getMaxS(); ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
ptrTex->x= 0.0; ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
}
returnTEX_OK;
}
voidParticleSystem::setDefaultParticleTex()
{
if(particleTexPtr)
deleteparticleTexPtr;
GLubyte*buffer = new GLubyte[8 * 8 * 4];
memset(buffer,255, 8*8*4);//white colour
particleTexPtr= new MYTexture(32,16711680/*third byte pattern*/,65280/*second bytepattern*/,255/*first byte pattern*/
,8,8,buffer);
delete[]buffer;
data.particleTexFileName= wxString("");
}
doubleParticleSystem::getX() const
{
returncurrentX;
}
doubleParticleSystem::getY() const
{
returncurrentY;
}
voidParticleSystem::setX(double x)
{
data.initialX= currentX = x;
}
voidParticleSystem::setY(double y)
{
data.initialY= currentY = y;
}
doubleParticleSystem::getSpeedChangeX() const
{
returndata.speedChangeX;
}
doubleParticleSystem::getSpeedChangeY() const
{
returndata.speedChangeY;
}
voidParticleSystem::setSpeedChangeX(double speed)
{
data.speedChangeX= speed;
}
voidParticleSystem::setSpeedChangeY(double speed)
{
data.speedChangeY= speed;
}
doubleParticleSystem::getStopDelay() const
{
returndata.stopDelay;
}
doubleParticleSystem::getStartDelay() const
{
returndata.startDelay;
}
voidParticleSystem::setStopDelay(double time)
{
data.stopDelay= time;
}
voidParticleSystem::setStartDelay(double time)
{
data.startDelay= time;
}
doubleParticleSystem::getLifeTime() const
{
returndata.pLifeTime;
}
voidParticleSystem::setLifeTime(double time)
{
data.pLifeTime= time;
}
doubleParticleSystem::getParticleAppearDelay() const
{
returndata.pAppearDelay;
}
voidParticleSystem::setParticleAppearDelay(double time)
{
data.pAppearDelay= time;
}
doubleParticleSystem::getMoveSpeedX() const
{
returndata.pMoveSpeedX;
}
doubleParticleSystem::getMoveSpeedY() const
{
returndata.pMoveSpeedY;
}
voidParticleSystem::setMoveSpeedX(double speed)
{
data.pMoveSpeedX= speed;
}
voidParticleSystem::setMoveSpeedY(double speed)
{
data.pMoveSpeedY= speed;
}
doubleParticleSystem::getGravityX() const
{
returndata.pGravityX;
}
doubleParticleSystem::getGravityY() const
{
returndata.pGravityY;
}
voidParticleSystem::setGravityX(double gravity)
{
data.pGravityX= gravity;
}
voidParticleSystem::setGravityY(double gravity)
{
data.pGravityY= gravity;
}
intParticleSystem::getMaxCount() const
{
returndata.pMaxCount;
}
voidParticleSystem::setMaxCount(int count)
{
data.pMaxCount= count;
if(data.pCountOnStart> data.pMaxCount)
data.pCountOnStart= data.pMaxCount;
}
intParticleSystem::getCountOnStart() const
{
returndata.pCountOnStart;
}
voidParticleSystem::setCountOnStart(int count)
{
data.pCountOnStart= count;
}
MYSize2DParticleSystem::getAppearBoxSize() const
{
returndata.pAppearBoxSize;
}
voidParticleSystem::setAppearBoxSize(MYSize2D box)
{
data.pAppearBoxSize= box;
}
doubleParticleSystem::getRedBegin() const
{
returndata.pRedBegin;
}
doubleParticleSystem::getGreenBegin() const
{
returndata.pGreenBegin;
}
doubleParticleSystem::getBlueBegin() const
{
returndata.pBlueBegin;
}
doubleParticleSystem::getAlphaBegin() const
{
returndata.pAlphaBegin;
}
voidParticleSystem::setRedBegin(double red)
{
data.pRedBegin= red;
}
voidParticleSystem::setGreenBegin(double green)
{
data.pGreenBegin= green;
}
voidParticleSystem::setBlueBegin(double blue)
{
data.pBlueBegin= blue;
}
voidParticleSystem::setAlphaBegin(double alpha)
{
data.pAlphaBegin= alpha;
}
doubleParticleSystem::getRedEnd() const
{
returndata.pRedEnd;
}
doubleParticleSystem::getGreenEnd() const
{
returndata.pGreenEnd;
}
doubleParticleSystem::getBlueEnd() const
{
returndata.pBlueEnd;
}
doubleParticleSystem::getAlphaEnd() const
{
returndata.pAlphaEnd;
}
voidParticleSystem::setRedEnd(double red)
{
data.pRedEnd= red;
}
voidParticleSystem::setGreenEnd(double green)
{
data.pGreenEnd= green;
}
voidParticleSystem::setBlueEnd(double blue)
{
data.pBlueEnd= blue;
}
voidParticleSystem::setAlphaEnd(double alpha)
{
data.pAlphaEnd= alpha;
}
doubleParticleSystem::getRotateAngle() const
{
returndata.pAngleRotate;
}
voidParticleSystem::setRotateAngle(double angle)
{
data.pAngleRotate= angle;
}
doubleParticleSystem::getKFScaleBeginW() const
{
returndata.pKFScaleBeginW;
}
doubleParticleSystem::getKFScaleBeginH() const
{
returndata.pKFScaleBeginH;
}
voidParticleSystem::setKFScaleBeginW(double scale)
{
data.pKFScaleBeginW= scale;
}
voidParticleSystem::setKFScaleBeginH(double scale)
{
data.pKFScaleBeginH= scale;
}
doubleParticleSystem::getKFScaleEndW() const
{
returndata.pKFScaleEndW;
}
doubleParticleSystem::getKFScaleEndH() const
{
returndata.pKFScaleEndH;
}
voidParticleSystem::setKFScaleEndW(double scale)
{
data.pKFScaleEndW= scale;
}
voidParticleSystem::setKFScaleEndH(double scale)
{
data.pKFScaleEndH= scale;
}
doubleParticleSystem::getKFDispersionX() const
{
returndata.pKFDispersionX;
}
doubleParticleSystem::getKFDispersionY() const
{
returndata.pKFDispersionY;
}
voidParticleSystem::setKFDispersionX(double disp)
{
data.pKFDispersionX= disp;
}
voidParticleSystem::setKFDispersionY(double disp)
{
data.pKFDispersionY= disp;
}
wxStringParticleSystem::getParticleTexFileName() const
{
returndata.particleTexFileName;
}
voidParticleSystem::copyDataFromParticleSystem(ParticleSystem* sys_from)
{
if(!sys_from)
return;
data.pLifeTime= sys_from->data.pLifeTime;
data.pMaxCount= sys_from->data.pMaxCount;
data.pCountOnStart= sys_from->data.pCountOnStart;
data.pGravityX= sys_from->data.pGravityX;
data.pGravityY= sys_from->data.pGravityY;
//p.speed,dispersion page
data.pMoveSpeedX= sys_from->data.pMoveSpeedX;
data.pMoveSpeedY= sys_from->data.pMoveSpeedY;
data.pKFDispersionX= sys_from->data.pKFDispersionX;
data.pKFDispersionY= sys_from->data.pKFDispersionY;
//p.scalepage
data.pKFScaleBeginW= sys_from->data.pKFScaleBeginW;
data.pKFScaleBeginH= sys_from->data.pKFScaleBeginH;
data.pKFScaleEndW= sys_from->data.pKFScaleEndW;
data.pKFScaleEndH= sys_from->data.pKFScaleEndH;
//p.colorpage
data.pRedBegin= sys_from->data.pRedBegin;
data.pGreenBegin= sys_from->data.pGreenBegin;
data.pBlueBegin= sys_from->data.pBlueBegin;
data.pAlphaBegin= sys_from->data.pAlphaBegin;
data.pRedEnd= sys_from->data.pRedEnd;
data.pGreenEnd= sys_from->data.pGreenEnd;
data.pBlueEnd= sys_from->data.pBlueEnd;
data.pAlphaEnd= sys_from->data.pAlphaEnd;
//rotate
data.pAngleRotate= sys_from->data.pAngleRotate;
//startin, stop in page
data.startDelay= sys_from->data.startDelay;
data.stopDelay= sys_from->data.stopDelay;
data.pAppearDelay= sys_from->data.pAppearDelay;
//PSsettings page
data.pAppearBoxSize= sys_from->data.pAppearBoxSize;
data.speedChangeX= sys_from->data.speedChangeX;
data.speedChangeY= sys_from->data.speedChangeY;
setX(sys_from->data.initialX);
setY(sys_from->data.initialY);
if(sys_from->data.particleTexFileName== "")
setDefaultParticleTex();
else
setParticleTex(sys_from->data.particleTexFileName);
}
boolParticleSystem::isRun() const
{
returnisRunb;
}
boolParticleSystem::isFinished() const
{
returnisFinishedb;
}
voidParticleSystem::start()
{
isRunb= true;
isFinishedb= false;
restart();
}
voidParticleSystem::stop()
{
isRunb= false;
}
voidParticleSystem::stopExtra()
{
isRunb= false;
finish();
}
voidParticleSystem::finish()
{
isFinishedb= true;
currentX= data.initialX;
currentY= data.initialY;
}
voidParticleSystem::restart()
{
startInTime= data.startDelay;
stopInTime= data.stopDelay;
timeForNextParticle= data.pAppearDelay;
intcount = data.pCountOnStart;
for(int i=0; i
{
if(count > 0)
{
initParticleAtIndex(i);
count--;
}
else
{
pTM[i]= 0;
}
}
}
voidParticleSystem::initParticleAtIndex(int i)
{
assert(i>= 0 && i
pTM[i]= data.pLifeTime;
pX[i]= fmod(rand(), data.pAppearBoxSize.width);
pY[i]= fmod(rand(), data.pAppearBoxSize.height);
doublespeedDeltaX = fmod(rand(), data.pKFDispersionX * 2 + 1) — data.pKFDispersionX;
pDx[i]= data.pMoveSpeedX + speedDeltaX;
doublespeedDeltaY = fmod(rand(), data.pKFDispersionY * 2 + 1) — data.pKFDispersionY;
pDy[i]= data.pMoveSpeedY + speedDeltaY;
}
voidParticleSystem::drawBound()
{
doubleappear_w = data.pAppearBoxSize.width;
doubleappear_h = data.pAppearBoxSize.height;
//drawbound itself
glColor4d(boundColor.Red()/255.0,boundColor.Green()/255.0, boundColor.Blue()/255.0, boundColor.Alpha()/255.0);
glBegin(GL_POLYGON);
glVertex2d(currentX- BOUND_DIMENSION, currentY — BOUND_DIMENSION);
glVertex2d(currentX+ appear_w + BOUND_DIMENSION, currentY — BOUND_DIMENSION);
glVertex2d(currentX+ appear_w + BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);
glVertex2d(currentX- BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);
glEnd();
//drawinner part of bound
glColor4d(boundedRectColor.Red()/255.0,boundedRectColor.Green()/255.0, boundedRectColor.Blue()/255.0,
boundedRectColor.Alpha()/255.0);
glBegin(GL_POLYGON);
glVertex2d(currentX,currentY);
glVertex2d(currentX+ appear_w, currentY);
glVertex2d(currentX+ appear_w, currentY + appear_h);
glVertex2d(currentX,currentY + appear_h);
glEnd();
if(!particleTexPtr)
return;
//drawtexture on left-top
doubletex_w = particleTexPtr->getWidth();
doubletex_h = particleTexPtr->getHeight();
glEnable(GL_TEXTURE_2D);
GLintbinded;
glGetIntegerv(GL_TEXTURE_BINDING_2D,&binded);
glBindTexture(GL_TEXTURE_2D,particleTexPtr->getName());
glColor4d(1.0,1.0,1.0,1.0);
doublereal_tex_w, real_tex_h;
real_tex_w= min(appear_w, tex_w);
real_tex_h= min(appear_h, tex_h);
doublereal_tex_s, real_tex_t;
real_tex_s= particleTexPtr->getMaxS() * ((double)real_tex_w) / ((double)tex_w);
real_tex_t= particleTexPtr->getMaxT() * ((double)real_tex_h) / ((double)tex_h);
glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0);
glVertex2d(currentX,currentY);
glTexCoord2d(real_tex_s,0.0);//texCoord[0].x,texCoord[0].y);
glVertex2d(currentX+ real_tex_w, currentY);
glTexCoord2d(real_tex_s,real_tex_t);//texCoord[1].x,texCoord[1].y);
glVertex2d(currentX+ real_tex_w, currentY + real_tex_h);
glTexCoord2d(0.0,real_tex_t);
glVertex2d(currentX,currentY + real_tex_h);
glEnd();
glBindTexture(GL_TEXTURE_2D,binded);
glDisable(GL_TEXTURE_2D);
}
voidParticleSystem::draw()
{
if(!particleTexPtr)
return;
if(isFinishedb)
return;
//if(int(startInTime*maj_kof) > 0)
if(startInTime> 0.0)
return;
glMatrixMode(GL_MODELVIEW);
MYPoint2D*ptrVert = verCoord;
MYParticleColor*ptrColor = color;
intcount = 0;
doubleprogress, x, y, w, h, r, g, b, a;
boolis_rotate = (data.pAngleRotate != 0.0);
for(int i = 0; i
{
progress= pTM[i];
x= pX[i];
y= pY[i];
if(progress> 0.0)
{
progress/= data.pLifeTime;
w= (data.pKFScaleEndW + progress * (data.pKFScaleBeginW — data.pKFScaleEndW)) *particleTexPtr->getWidth();
h= (data.pKFScaleEndH + progress * (data.pKFScaleBeginH — data.pKFScaleEndH)) *particleTexPtr->getHeight();
if(is_rotate)
{
doublereal_alpha = fmod(data.pAngleRotate * 360.0 * progress, 360.0);
glPushMatrix();
glTranslated(x,y, 0.0);
glRotated(real_alpha,0.0, 0.0, 1.0);//clock wise direction
x= y = 0.0;
}
x-= w/2.0;//only CENTERS of particles initially placed in AppearingBox (0.5,0.5origin)
y-= h/2.0;//only CENTERS of particles initially placed in AppearingBox (0.5,0.5origin)
r= data.pRedEnd + progress * (data.pRedBegin — data.pRedEnd);
g= data.pGreenEnd + progress * (data.pGreenBegin — data.pGreenEnd);
b= data.pBlueEnd + progress * (data.pBlueBegin — data.pBlueEnd);
a= data.pAlphaEnd + progress * (data.pAlphaBegin — data.pAlphaEnd);
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r= r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
if(is_rotate)
{
double*m = viewMatrixCache;
glGetDoublev(GL_MODELVIEW_MATRIX,m);
doublex2 = x + w;
doubley2 = y + h;
double*tp = (double*)ptrVert;
ptrVert->x= m[0]*x + m[4]*y + m[12];ptrVert->y = m[1]*x + m[5]*y + m[13];ptrVert++;
ptrVert->x= m[0]*x2 + m[4]*y + m[12];ptrVert->y = m[1]*x2 + m[5]*y + m[13];ptrVert++;
ptrVert->x= m[0]*x2 + m[4]*y2 + m[12];ptrVert->y = m[1]*x2 + m[5]*y2 + m[13]; ptrVert++;
ptrVert->x= tp[0]; ptrVert->y = tp[1]; ptrVert++;
ptrVert->x= tp[4]; ptrVert->y = tp[5]; ptrVert++;
ptrVert->x= m[0]*x + m[4]*y2 + m[12];ptrVert->y = m[1]*x + m[5]*y2 + m[13];ptrVert++;
glPopMatrix();
}
else
{
ptrVert->x= x;ptrVert->y = y;ptrVert++;
ptrVert->x= x+w;ptrVert->y = y;ptrVert++;
ptrVert->x= x+w;ptrVert->y = y+h;ptrVert++;
ptrVert->x= x;ptrVert->y = y;ptrVert++;
ptrVert->x= x+w;ptrVert->y = y+h;ptrVert++;
ptrVert->x= x;ptrVert->y = y+h;ptrVert++;
}
count++;
}
}
glPushMatrix();
glTranslated(currentX,currentY, 0.0);
glEnable(GL_TEXTURE_2D);
GLintbinded;
glGetIntegerv(GL_TEXTURE_BINDING_2D,&binded);
glBindTexture(GL_TEXTURE_2D,particleTexPtr->getName());
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2,GL_DOUBLE, 0, verCoord);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_DOUBLE, 0, texCoord);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4,GL_DOUBLE, 0, color);
glDrawArrays(GL_TRIANGLES,0, count*6);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D,binded);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
boolParticleSystem::save(TiXmlElement* root_ptr) const
{
TiXmlElementelement(«PS»);
element.SetAttribute(TEXTURE_ATTR,data.particleTexFileName);
element.SetDoubleAttribute(LIFE_TIME_ATTR,data.pLifeTime);
element.SetDoubleAttribute(APPEAR_DELAY_ATTR,data.pAppearDelay);
element.SetDoubleAttribute(PARTICLE_SPEED_X_ATTR,data.pMoveSpeedX);
element.SetDoubleAttribute(PARTICLE_SPEED_Y_ATTR,data.pMoveSpeedY);
element.SetDoubleAttribute(GRAVITY_X_ATTR,data.pGravityX);
element.SetDoubleAttribute(GRAVITY_Y_ATTR,data.pGravityY);
element.SetAttribute(MAX_COUNT_ATTR,data.pMaxCount);
element.SetAttribute(START_COUNT_ATTR,data.pCountOnStart);
element.SetDoubleAttribute(APPEAR_BOX_W_ATTR,data.pAppearBoxSize.width);
element.SetDoubleAttribute(APPEAR_BOX_H_ATTR,data.pAppearBoxSize.height);
element.SetDoubleAttribute(RED_BEGIN_ATTR,data.pRedBegin);
element.SetDoubleAttribute(RED_END_ATTR,data.pRedEnd);
element.SetDoubleAttribute(GREEN_BEGIN_ATTR,data.pGreenBegin);
element.SetDoubleAttribute(GREEN_END_ATTR,data.pGreenEnd);
element.SetDoubleAttribute(BLUE_BEGIN_ATTR,data.pBlueBegin);
element.SetDoubleAttribute(BLUE_END_ATTR,data.pBlueEnd);
element.SetDoubleAttribute(ALPHA_BEGIN_ATTR,data.pAlphaBegin);
element.SetDoubleAttribute(ALPHA_END_ATTR,data.pAlphaEnd);
element.SetDoubleAttribute(SCALE_BEGIN_W_ATTR,data.pKFScaleBeginW);
element.SetDoubleAttribute(SCALE_BEGIN_H_ATTR,data.pKFScaleBeginH);
element.SetDoubleAttribute(SCALE_END_W_ATTR,data.pKFScaleEndW);
element.SetDoubleAttribute(SCALE_END_H_ATTR,data.pKFScaleEndH);
element.SetDoubleAttribute(DISPERSION_X_ATTR,data.pKFDispersionX);
element.SetDoubleAttribute(DISPERSION_Y_ATTR,data.pKFDispersionY);
element.SetDoubleAttribute(PS_X_ATTR,data.initialX);
element.SetDoubleAttribute(PS_Y_ATTR,data.initialY);
element.SetDoubleAttribute(PS_SPEED_X_ATTR,data.speedChangeX);
element.SetDoubleAttribute(PS_SPEED_Y_ATTR,data.speedChangeY);
element.SetDoubleAttribute(START_DELAY_ATTR,data.startDelay);
element.SetDoubleAttribute(STOP_DELAY_ATTR,data.stopDelay);
element.SetDoubleAttribute(ROTATE_ATTR,data.pAngleRotate);
TiXmlElement*ptr_element = (TiXmlElement*)root_ptr->InsertEndChild(element);
return((bool)(ptr_element!= NULL));
}
boolParticleSystem::load(TiXmlElement*& element_ptr)
{
TiXmlElement*next_element_ptr = (TiXmlElement*)element_ptr->FirstChild(«PS»);
if(!next_element_ptr)
{
next_element_ptr= (TiXmlElement*)element_ptr->NextSibling(«PS»);
if(!next_element_ptr)
returnfalse;
}
//readversion 1.1 parameters
if(next_element_ptr->QueryIntAttribute(MAX_COUNT_ATTR,&data.pMaxCount) != TIXML_SUCCESS)
data.pMaxCount= EXPL_MAX;
//readall version parameters (obligatory)
if(next_element_ptr->QueryIntAttribute(START_COUNT_ATTR,&data.pCountOnStart) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(LIFE_TIME_ATTR,&data.pLifeTime) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_DELAY_ATTR,&data.pAppearDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PARTICLE_SPEED_X_ATTR,&data.pMoveSpeedX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PARTICLE_SPEED_Y_ATTR,&data.pMoveSpeedY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GRAVITY_X_ATTR,&data.pGravityX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GRAVITY_Y_ATTR,&data.pGravityY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_BOX_W_ATTR,&data.pAppearBoxSize.width) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_BOX_H_ATTR,&data.pAppearBoxSize.height) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(RED_BEGIN_ATTR,&data.pRedBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(RED_END_ATTR,&data.pRedEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GREEN_BEGIN_ATTR,&data.pGreenBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GREEN_END_ATTR,&data.pGreenEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(BLUE_BEGIN_ATTR,&data.pBlueBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(BLUE_END_ATTR,&data.pBlueEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ALPHA_BEGIN_ATTR,&data.pAlphaBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ALPHA_END_ATTR,&data.pAlphaEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_BEGIN_W_ATTR,&data.pKFScaleBeginW) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_BEGIN_H_ATTR,&data.pKFScaleBeginH) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_END_W_ATTR,&data.pKFScaleEndW) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_END_H_ATTR,&data.pKFScaleEndH) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(DISPERSION_X_ATTR,&data.pKFDispersionX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(DISPERSION_Y_ATTR,&data.pKFDispersionY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_X_ATTR,&data.initialX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_Y_ATTR,&data.initialY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_SPEED_X_ATTR,&data.speedChangeX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_SPEED_Y_ATTR,&data.speedChangeY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(START_DELAY_ATTR,&data.startDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(STOP_DELAY_ATTR,&data.stopDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ROTATE_ATTR,&data.pAngleRotate) != TIXML_SUCCESS)
returnfalse;
currentX= data.initialX;
currentY= data.initialY;
setParticleTex(next_element_ptr->Attribute(TEXTURE_ATTR));
element_ptr= next_element_ptr;
returntrue;
}
voidParticleSystem::callback(double sec_interval)
{
if(isFinishedb)
return;
//checkfor startInTime
startInTime-= sec_interval;
//if(((int)startInTime*maj_kof) > 0)
if(startInTime> 0.0)
return;
else
startInTime= 0.0;
//changeDX DY
currentX+= data.speedChangeX* sec_interval;
currentY+= data.speedChangeY* sec_interval;
//checkfor the next particle
timeForNextParticle-= sec_interval;
doubleaddParticleTime = 1.0;
if(timeForNextParticle
{
addParticleTime= timeForNextParticle;
timeForNextParticle= data.pAppearDelay;
}
boolneed_to_finish = true;
if(isRunb)
{
need_to_finish= false;
stopInTime-= sec_interval;
//if(((int)stopInTime*maj_kof)
if(stopInTime
stop();
}
//calculateentire number of particles alive
intcurr_numof_particles = 0;
for(inti=0; i
if(pTM[i]> 0.0)
++curr_numof_particles;
//processparticles
for(int i=0; i
{
pTM[i]-= sec_interval;
if(pTM[i]
{
if(addParticleTime
{
//addnew particle
addParticleTime+= data.pAppearDelay;
++curr_numof_particles;
initParticleAtIndex(i);
}
}
else
{
need_to_finish= false;
pX[i]+= sec_interval * pDx[i];
pY[i]+= sec_interval * pDy[i];
pDx[i]+= sec_interval * data.pGravityX;
pDy[i]+= sec_interval * data.pGravityY;
}
}
if(need_to_finish)
finish();
}
voidParticleSystem::setBoundColor(wxColour color)
{
boundColor= color;
}
wxColourParticleSystem::getBoundColor()
{
returnboundColor;
}