Contents
3 - External Interface Requirements
1.1 -
Purpose
This
document provides an outline of the St Vincent Driving Simulator as a whole and
describes the first iteration of development to create a functional prototype.
1.2 -
Document conventions
This
document describes the components of the St Vincent Driving Simulator in 6
sections ranging from General Overview and Functional Requirements to
Non-Functional Requirements.
In a
couple of the sections in this document, namely Sections 2 and 4, exists the
bulk of the implementation and design for the project respectively.
1.3 -
Intended audience
Project
Managers
Development
Team
Users of
this software with the goal of modifying its structure
1.4 -
Additional Information
As an
open source project hosting has been provided by Sourceforge.net
SVN: https://svc-driving-sim.svn.sourceforge.net/svnroot/svc-driving-sim
Web: http://svc-driving-sim.sourceforge.net/
In
addition to an external steering wheel interface DarkGDK will be used as a
front end to DirectX to aid in the creation of a 3D environment.
Definitions
For definition of common terminology used in this document please
refer to Section 6 Appendix A.
License
This work uses the Creative Commons Attribution-Share Alike 3.0
United States license which can be reviewed in Section 6 Appendix B.
1.5 -
Contact information/SRS team members
Project
Development
Paul
Scarrone
Email:
Paul.Scarrone@email.stvincent.edu
Anthony
Williams
Email:
anthony.williams@email.stvincent.edu
Josh
Woods
Email: josh.woods@email.stvincent.edu
Nathan
Hoffer
Email: nathan.hoffer@email.stvincent.edu
Riley
Hardin
Email: riley.hardin@email.stvincent.edu
Sarah
Anderson
Email: sarah.anderson@email.stvincent.edu
This
Documentation
Paul
Scarrone
Email:
Paul.Scarrone@email.stvincent.edu
Anthony
Williams
Email:
anthony.williams@email.stvincent.edu
Josh
Woods
Email: josh.woods@email.stvincent.edu
Nathan
Hoffer
Email: nathan.hoffer@email.stvincent.edu
Riley
Hardin
Email: riley.hardin@email.stvincent.edu
Sarah
Anderson
Email: sarah.anderson@email.stvincent.edu
Brendan
Bartko
Email: brendan.bartko@email.stvincent.edu
2.1 -
Product perspective
The St. Vincent College Driving Simulator is an interdepartmental
project between Dr. Mark Rivardo of the Psychology department and the Computer
Science department under the supervision of Dr. Cynthia Martincic. The
Psychology department requested a system to generate reliable reports based
upon human reactions to stimuli in the form of driver distractions. Currently
the department uses a manual approach to distract and to gather statistics
through interacting with the subject and observing the subjects reaction times.
A system was desired to allow for my systematic and accurate tracking of test
data. Through consultation with Dr. Mark Rivardo it was discovered that a new
system would have to be created to meet these needs. The application would be
required to us 3D computer technology to generate an environment for testing
and an accurate system to track and report the test subject. The decision was
made to use the DarkGDK library in C++ to reduce the start-up time regarding
the 3D requirements of the simulator. As a student project there is an absence
of experience required realize this as a complete application, but it will be
possible to create an initial proof of concept that can act as a prototype
solution with the most essential requirements met. This prototype will be
essential for continued development and a final deliverable.
2.2 -
Product functions
2.2.1 - Use Case Related to Driving
2.2.1.1 - First Person
Driving
Use Case
The user shall view the driving course and all events generated by
the system from the first person perspective as if in the driver’s seat of a
car. The primary purpose of requiring a first person perspective is to greater
the immersion of the user in the experience of driving. While this is a
simulation, a properly maintained suspension of disbelief should provide
greater accuracy in testing results.
Description
Additional factors that attribute to the goal of immersing the
user in the simulated driving experience are those items which are related
experientially to the act of driving; Speed, Acceleration, Turning Rate,
Turning Pivot, Braking, and Field of View.
2.2.2 - Use Case Relate to First
Iteration
2.2.2.1 - Prototype
Use Case
The end user is not the target of this
use case. The target is to provide a functional system that can guarantee the
viability of the project. This is accomplished by proving that a 3D environment
can be created, relevant data can be tracked and manipulated, and accurate reports
can be generated from each simulation session.
Diagram
2.2.2.1.1
2.3 -
User Classes and Characteristics
2.3.1 – CoordBlock
Struct
Vertex3d:
Purpose:
The Vertex3d struct stores three values that represent a vertex in
three dimensional space.
Code Description:
The Vertex3d struct contains three float variables named “x”, “y”,
and “z” each corresponding to a coordinate value in a vertex.
Struct
Vertex2d:
Purpose:
The Vertex2d struct stores two values as a vertex in two
dimensional space.
Code Description:
The Vertex2d struct contains two float variables named “x” and “y”
each corresponding to a coordinate value in a vertex.
Class
CoordBlock:
Purpose:
The purpose of the class CoordBlock is to allow the classification
and storage of all the necessary coordinate information in the form that the
MemBlock can utilize to create a mesh. A key aspect of this class is its
ability to create a CoordBlock object from vertex and diffuse color values for
a coordinate. The vertex value can be in the form of a Vertex3d struct or in
the form of three distinct float values.
Requirements:
This class uses Vertex2d and Vertex3d structs in its private
members.
Code Description:
There are two constructors for creating objects of the class
CoordBlock. In the first constructor, three float values, each corresponding to
a coordinate in a three-dimensional vertex, and a Boolean value can be passed
into the constructor. The Boolean value indicates whether or not to complete
the remaining CoordBlock private members through instantiation. In the second
constructor, a Vertex3d and diffuse color are passed to initialize all of the
private members of the CoordBlock class. There are also two functions that help
complete the instantiation of CoordBlock private members. The last function is
applied by setting the CoordBlock’s diffuse color to the diffuse color passed
into the function.
2.3.1.2 - CRC
Vertex2d
Struct Properties:
float x
float y
Vertex3d
Struct Properties:
float x
float y
float z
CoordBlock
Class Properties:
Vertex3d vertex
Vertex3d normal
Vertex2d uv
DWORD diffuse
Method Prototypes:
CoordBlock()
CoordBlock(float x, float y, float z, bool autoComplete)
CoordBlock(Vertex3d vertex, DWORD dColor)
void CompleteCoordBlock(Vertex3d vertex)
void CompleteCoordBlock(Vertex3d vertex, float z)
void SetDiffuseColor(DWORD diffuse)
Inheritance
None
2.3.1.1 - Sequence Diagram
2.3.2 - DoubleLinkedList
Purpose:
This class is a templated doubly linked list class.
Requirements:
This class has no requirements.
Code Description:
This class contains a node structure that holds Node data, a
pointer to the previous node, and a pointer to the next node. Basic linked list
functions such as push_back(T), push_front(T), pop_back( ), pop_front( ),
CopyList( ), empty( ), and GetSize( ) perform the actions described by their
names. The function CopyList copies a list by creating a new DoubleLinked list
of length GetSize, traverses the existing DoubleLinked list, and adds equivalent
values of existing items to the new linked list as it processes.
2.3.2.2 - CRC
Class Properties:
struct node
node* head
node* tail
int size
Method Prototypes:
DoubleLinked()
DoubleLinked(Array[N])
bool empty()
void push_back(Data)
void push_front(Data)
Data pop_back()
Data pop_front()
void CopyList(DoubleLinked)
int GetSize()
~DoubleLinked()
Inheritance:
None
2.3.2.1 - Sequence Diagram
2.3.3 – ControlDeviceManager
Purpose:
This class provides a wrapper for existing DarkGDK systems
involving the polling of Direct Input compatible controllers. In DarkGDK items
polled from DirectX are ordered into an internal CheckList structure that gives
access to the items name and up to 4 attributes about the item polled. To make
handling selection of a controller less complicated s structure is defined to
hold the item name and up to 4 attributes that can be accessed as an array of
objects. Array creation is handled by this class and provides methods of
external access.
Requirements:
This class depends upon the DarkGDK subsystem and compatible
DirectInput devices.
Code Description:
This class carries its own definition for a structure which
contains the options that DarkGDK extracts when polling and creating an
internal Checklist. This class consists of a single constructor which upon
instantiation completes the checklist object. This class contains, 2 accessor
functions for the checklist size and to access the checklist itself and 2
methods. These methods handle the initial polling of the system for devices and
the passing of that information into the checklist structure. The code flows
from this constructor directly to these two methods in series without the need
for input from the user. At any time, if a re-polling must be done, the checklist
can be recreated without the need of a new object by using the
CreateCheckList() method at any time from the original object.
2.3.3.1 - Sequence Diagram
2.3.3.2 – CRC
Class Properties:
int size
CheckList* checkList
Method Prototypes:
ControlDeviceManager()
void CreateCheckList()
void ProcessCheckListItem()
Checklist* GetCheckList()
int GetCheckListSize()
Inheritance:
None
2.3.4 – ParseVector
Purpose:
The
purpose of the class ParseVector is to allow a file that contains vector points
of x, y, and z coordinates to be read and correctly stored in an array in order
for these vector points to be utilized by other classes in the project.
Requirements:
It
is important to note that for the vector points to be read in by the program properly,
there must be a comma after each coordinate in a vector point, including the
last coordinate (e.g. “1, 2, 3,”). In addition, after the comma of the last
coordinate of a point a new line is started for the next new vector point, and
there is no new line after the last vector point in the file. Each vector point
is expected to have three coordinate values, one x, one y, and one z.
Creating Points for the Vector:
This
information is not essential to the program correctly working but aids whoever
may need to create vectors with new points. Begin with the initial point of the
vector as the point (0, 0, 0). Then with a graphing device (such as a graphing
calculator), graph a circle with a radius of ten and make its center the
previous initial point (0, 0, 0). Trace along the circumference of the circle
and select a point. This selected point is the next new vector point. Thus, add
this new point to the text file containing the list of vector points. Use as many decimal places as possible when
recording the vector points in order for the vector points and calculations
with the vector points to be very precise. Next move the circle with a radius
of ten so that the center of the circle is at the new vector point. Then
repeating the process before, select another point from along the
circumferences of the circle as the next new vector point. Repeat this
procedure of translating the circle and selecting and recording a new vector
point until there is a total of ten vector points in the vector points list in
the text file.
Code description:
A
key functionality of this class is reading in a text file. This is accomplished
by using the fstream library class. Using fstream, the appropriate indicated
text file can be opened by the ParseVector class, and then each line is read in
by the fstream function getline(). The
result of the getline() function is returned in a character array which is
stored in a temporary variable and used to translate the data into a string,
which is stored in another string variable. Then using character array of the
single line of data, each character is tested to see if it matches a comma. If
a comma is found, then the substring function is used on the variable
containing the string of line data, utilizing a variable that stores the
desired start position for each substring and the current position in the
character array. The value extracted from the string is then converted into a
float value. Then according to the indicator variable, which indicates the
coordinate in the vector that has been extracted (0 for x, 1 for y, and 2 for
z), this float value is stored into the correct position in an array as the
appropriate coordinate of a vector point. This process is continued until the
end of the text file is reached, indicating all the data has been read and
stored in the array. An additional functionality of the class is that a
CoordBlock array can be built from the Vertex3d array used to store all the
vector points from the text file. This is accomplished by passing in a
CoordBlock array by reference and then adding the appropriate point data from
the entire Vertex3d array to the CoordBlock array. Thus after all the Vertex3d
array data has been inserted into the CoordBlock array, the completed
CoordBlock array is passed back by reference and can be utilized by the other
classes in the project.
2.3.4.1 - Sequence Diagram
2.3.4.2 – CRC
Class Properties:
Vertex3d* vectorPoints
CoordBlock* coordArrayTemp
int arraySize
DWORD diffuseColor
Method Prototypes:
ParseVector()
ParseVector(char* filename)
void ProcessVectorFile(char* filename)
void SetDiffuseColor(DWORD color)
int GetVectorFileLength(char* filename)
int GetArraySize()
void GetVectorCoordBlock(CoordBlock (&coordArray2)[N])
void CopyVectorCoordBlock()
Inheritance:
None
2.3.5 - DrawIrregularPoly
Purpose:
As
a final step in the road generation process this specialized class passes data
into a DarkGDK MemBlock structure for use in creating a static reusable mesh
from a single series of spatial coordinates. All constituent requirements to
handle MemBlock data are completed in this class but creation of the MemBlock
is reliant on additional external classes.
Requirements:
Since
this class does not perform any data processing it requires in its overloaded
form an array of points that it can pass to the BuildDrawList class and parse
through the list of spatial objects it receives in return. MemBlock size and
position information is calculated by knowing the initial size of the data set
being passed int to the constructor. Also due to this being the final step in
creating a mesh object this class creates a formatted data file of all
positions for each vertex within the new mesh alongside the creation of the
MemBlock. There are no sequence requirements for a MemBlock, so the data must
be in the correct order when brought in for processing.
MemBlock Criteria:
MemBlocks
are a binary file format with a 96bit header followed by 288bits multiplied by
the number of vertices in the original input. This file type can be manipulated
both as a binary file and as a memory object and then converted into a static
mesh represented as a single object. MemBlock size is represented in bytes
using the equation [96bit + ( Number of Vertices x ( 3 x 96bit)] / 8bit
MemBlock Specification:
MemBlock
Header Information 96 Bits |
|||
Type |
Value |
Hex |
Description |
Dword |
338 |
52 01 00 00 |
FVF Format Type
(Flexible Vertex Format) |
Dword |
36 |
24 00 00 00 |
FVF Size – The size
of a block of coordinates |
Dword |
6 |
06 00 00 00 |
Number of Vertices
(VertexNum) |
Coordinate
Block (FVF Size * (3 * 96)Bits --- Repeats a VertexNum number of times |
|||
Spatial
Coordinates |
|||
Float |
5 |
00 00 A0 40 |
Vertex X |
Float |
5 |
00 00 A0 40 |
Vertex Y |
Float |
0 |
00 00 00 00 |
Vertex Z |
Normals
Coordinates |
|||
Float |
5 |
00 00 A0 40 |
Normal at Vertex X |
Float |
5 |
00 00 A0 40 |
Normal at Vertex Y |
Float |
0 |
00 00 00 00 |
Normal at Vertex Z |
Diffuse
Color |
|||
Dword |
1065353216 |
00 00 80 3F |
Object color under
white light |
UV
Coordinates |
|||
Float |
0 |
00 00 00 00 |
UV at Vertex X |
Float |
5 |
00 00 A0 40 |
UV at Vertex Y |
Sample
MemBlock generated by DarkGDK :
52 01 00 00 24 00 00 00 06 00 00 00 00 00 A0 40 00 00 A0 40 00 00 00 00 00 00 A0 40 00 00 A0 40 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 40 00 00 A0 C0 00 00 A0 40 00 00 00 00 00 00 A0 C0 00 00 A0 40 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 40 00 00 A0 C0 00 00 A0 C0 00 00 00 00 00 00 A0 C0 00 00 A0 C0 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 C0 00 00 A0 40 00 00 A0 40 00 00 00 00 00 00 A0 40 00 00 A0 40 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 40 00 00 A0 40 00 00 A0 C0 00 00 00 00 00 00 A0 40 00 00 A0 C0 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 C0 00 00 A0 C0 00 00 A0 C0 00 00 00 00 00 00 A0 C0 00 00 A0 C0 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 A0 C0
Code Description:
The
class directly pushes the objects from a list type to a MemBlock. Upon
overloaded instantiation class calculates the size of the MemBlock and writes
the header followed by the objects spatial coordinates in series. Writing
position is handled by absolute location based upon the sequence number of the
item being written to MemBlock. Sequential item position is handled by
positioning the MemBlock pointer the distance in bytes of the last data item
entered. Once completed the MemBlock is dumped to a file automatically so an
object can be created without reprocessing.
2.3.5.1 - Sequence Diagram
2.3.5.2 – CRC
Class Properties:
int fvfStyle
int fvfVertexSize
Method Prototypes:
DrawIrregularPoly(CoordBlock (&coordArray)[N])
DrawIrregularPoly(DoubleLinked<CoordBlock> &list)
void MakeMemBlockIntoFile(int memblockIndex, char* filename)
void WriteFVF338Header(int memblockIndex, long vertexNum)
int CalcMemBlockSize(int vertices)
void WriteCoordBlock(int blockNum,CoordBlock cBlock, int
memblockIndex)
Inheritance:
None
2.3.6 - MemblockParser
Purpose:
The purpose of this class is to simply read in information from a
file and construct a MemBlock. Once the
MemBlock is created, it is pushed into a list of type CoordBlock. After the information is pushed into the
list, the created MemBlock is destroyed.
This class efficiently creates the CoordBlock list to aid in creation of
the road.
Requirements:
This class requires the information being read in from the file to
be in the correct format. The
information must have a header which will tell how many vertices must be read
in. This class also requires the use of
its overloaded constructor.
Code Description:
First, the code sets up a structure for the MemBlock healer. It includes the fvfStyle, fvfVertexSize, and
the vertexNum. Then, the code begins
reading in the information from the file.
The memblockId is created along with the header for the MemBlock. Once the foundation is created, the
information is read into the MemBlock.
Then, the MemBlock is created and is pushed into the list of type
CoordBlock. Finally, the MemBlock is
deleted.
2.3.6.1 - Sequence Diagram
2.3.6.2 – CRC
Class Properties:
int memblockId
DoubleLinked<CoordBlock> list
CoordBlock tempCoordBlock
MemblockHeader header
Method Prototypes:
MemblockParser()
emblockParser(int memblockId)
void ReadFVFHeader()
void ReadMemblock()
MemblockHeader GetFVFHeader()
Inheritance:
BuildRoadLinesList
2.3.7 - BuildRoadLinesList
Purpose:
The purpose of this class is to accept a passed DoubleLinked
CoordBlock list and from this list build the right, left, and center line
drawing lists. The passed DoubleLinked CoordBlock list is the list containing
the drawing order of the vertices of the road surface. The class uses this list
for each road line by looping through the drawing order list, selecting the
correct vertex, and storing the vertex in the appropriate road line drawing
list. After a BuildRoadLinesList object is constructed and initialized, the
object will store three separate DoubleLinked CoordBlock list, one for each
road line. The class allows the road line drawing lists to be utilized by other
class by having an accessor function for each road line draw list.
Requirements:
In order for this class to work appropriately, the DoubleLinked
CoordBlock list passed in for construction or initialization must be the
correct drawing order list for the road surface. This is necessary because the
road’s vertices are stored in a specific pattern which is then used by this
class in selecting the right vertices for each road line drawing list. Using
any other DoubleLinked CoordBlock list or format for the list will result in
road lines that will not appear correctly on the roads surface. The suggested
way of attaining the proper DoubleLinked CoordBlock road surface drawing list
is with the GetCoordBlockList(DoubleLinked<CoordBlock> (&list2))
function of the MemblockParser class.
Code Description:
This class is functional only after it has been initialized by
using the DoubleLinked CoordBlock drawing order list. This process of
initialization is a separate function within the class. This initializing
function accepts the drawing order list and creates another version of the
drawing list as an array. It is significant that the drawing list is available
within the class as an array because when the drawing list is processed later
in the class, the array data structure will allow easy access to CoordBlock
data at the calculated positions in the list.
Within the initializing function, there are three function calls that
are made to build each road line drawing list. These three distinct functions
are similar in the manner in which they process the drawing order list to build
the proper drawing order list for each road line. The implementation pattern
these three functions follow include calculating the appropriate position in
the drawing order list for the needed CoordBlock vertex data, looping through
the class’s array version of the drawing order list to the calculated position,
storing the CoordBlock vertex data in a temporary variable, changing the
temporary variable’s z-value to -0.1, and storing the temporary variable in the
correct road line’s drawing list. The reasoning behind changing the z-value of
each road line CoordBlock vertex is that for the road lines to appear on the
screen, the lines must be draw slightly above the road surface. Therefore by
making the z-value of the road lines all -0.1, the lines will be above the road
surface, which is drawn with vertices that have a z-value of 0. It might seem
counterintuitive that a negative z-value is above a non-negative z-value.
However, this is how the z-axis is arranged in DarkGDK graphics. Once these
three functions have executed, the three road lines’ drawing lists will be
built, and the initializing function for the class will be complete. The class
then allows access to the three road lines’ drawing lists through three
accessor functions. These three accessor functions perform the same operation
but on different road lines. The operation involves making a copy of the
corresponding road line’s drawing list and passing the copied list by reference
to the parameter of the accessor function.
2.3.7.1 - Sequence Diagram
2.3.7.2 – CRC
Class Properties:
int drawingListSize;
CoordBlock* drawingList;
DoubleLinked<CoordBlock> rightLine;
DoubleLinked<CoordBlock> leftLine;
DoubleLinked<CoordBlock> centerLine;
Method Prototypes:
BuildRoadLinesList()
BuildRoadLinesList(DoubleLinked<CoordBlock> list)
void InitializeLines(DoubleLinked<CoordBlock> list)
void CreateRightLine()
void CreateLeftLine()
void CreateCenterLine()
void GetRightLine(DoubleLinked<CoordBlock>& list)
void GetLeftLine(DoubleLinked<CoordBlock>& list)
void GetCenterLine(DoubleLinked<CoordBlock>& list)
Inheritance
None
2.3.8 – CalculateNormals
Purpose:
The purpose of this class is to take in points on the center line
of our road surface and calculate the normals to the line created by the
inputted points. This will allow
accurate representation of the road’s width, equal distance on either side from
the road’s center line. This aids in our
vehicle tracking to know whether the vehicle is in the correct lane, incorrect
lane, or off the road.
Requirements:
This class requires use of the <math.h> library for use of
the square root function in the quadratic formula for calculating the normals
of the inputted points. This class also
requires that there are points available to be read for the creation of the
normal points. Currently, this class
only calculates the normals for the points assuming the points are all on a
flat plane where z = 0. However, the
code has been written to allow for easy expansion to calculate normals on the
z-axis.
Structure of a Coordinate:
Defined in coordstruct.h, a coordinate is a structure made up of
three points saved as floats. The three
points are x, y, and z. In
normalscalculation.h, structures are defined as arrays named pointsOutput[3]
and pointsInput[3]. The three inputted
points are the points of the center line of the road in order. They’re used to calculate the pointsOutput[3]
points. The first point in the outputted
points is the intersection of the slopes between the line constructed by the
inputted points and the normal of that line.
The remaining two outputted points are the normal points of a distance
of 10 float away from the first outputted point on the normal line.
Code Description:
This class defines a point 10 units away from the starting point
and perpendicular to the road vector. Next, these points are stored in an
array. Undefined slope is handled by comparing x values. If the x-coordinates
are equal, the points are in a vertical line.
Because the points are in a vertical line, normals calculation cannot
continue normally because that would create a division by zero error. If the x-coordinates of the tested points are
not equal, the slope between the lines is calculated, and then the slope of the
normal line is calculated. Following the
calculation of the slopes, the point at which the two lines intersect, is
calculated. Then, using the quadratic
formula, two points, each a distance of 10 float away from the point of
intersection on the normal line, are calculated and saved. This process repeats for the remaining points
to calculate the position of the road.
2.3.8.1 - Sequence Diagram
2.3.8.2 – CRC
Class Properties:
Vertex3d pointsOutput[3]
Vertex3d pointsInput[3]
float d
Method Prototypes:
CalculateNormals()
Vertex3d GetRightNormal(Vertex3d pointOne, Vertex3d pointTwo,
Vertex3d pointThree)
Vertex3d GetLeftNormal(Vertex3d pointOne, Vertex3d pointTwo,
Vertex3d pointThree)
void CalculateNormalPoints(Vertex3d pointsInput[], Vertex3d
pointsOutput[])
Vertex3d ExtendPoints(Vertex3d p1, Vertex3d p2)
Inheritance
None
2.3.9 – VehicleTools
Purpose:
The
purpose of this class is to set the vehicle controls to a manual setting. By pressing keys on the keyboard or using a
steering wheel and pedals, the vehicle should move accordingly to the buttons
pressed.
Requirements:
The requirements for this class are
coordstructs.h and DarkGDK.h.
Code Description:
This
class is used to place manual controls on the vehicle. The class begins by a single call, setting
the accessor for control properties.
Then, all of the controls are set to a default starting position. Next, there is an overloaded constructor
created that is used to permit instantiation with custom properties and vehicle
starting position. Once that has
finished, the program then takes a DarkGDK object ID and allows for control of
forward motion through acceleration and turning. Then, a 3D object ID is taken as a parameter
and allows for control with the controller set.
Finally, the camera is set to the vehicle ID and follows the manual
controls
2.3.9.1
- Sequence Diagram
2.3.9.2 – CRC
Class Properties:
Vertex3d carPos
Vertex3d camera
Vertex2d wheelPos
Vertex3d absCarPos
int vehicleId
float maxVelocity
float speedControlRate
float accelerationRate
float pedalMultiplier
float steeringMultiplier
float turningRate
bool vehicleCameraOn
Method Prototypes:
void
SetControlMultipliers(float wheel, float pedal, float turning, float
controlRate, float accel, float maxVel)
Vertex3d GetAbsCarPos()
VehicleTools()
VehicleTools(Vertex3d
vehPos, float wheel, float pedal, float turning, float controlRate, float
accel, float maxVel)
void
VehicleControlKeyboard(int vehicleId)
void
VehicleControlGameController(int vehicleId)
void
VehicleCameraControl(int vehicleId, float pos)
void SetupVehicleCamera(int
vehicleId)
void VehicleReset(int
vehicleId, Vertex3d pos)
Inheritance:
None
2.3.10 - BuildDrawList
Purpose:
This
class takes an object array of type CoordBlock that contain a linear series of
spatial points and extrapolates with the help of the CalculateNormals class. The absolute spatial coordinates that define
the vertices of a linear series of polygons will be draw along that original
linear array. This class performs an intermediate step of the object generation
process by aggregating the object data into a doubly linked list. This list is accessible
to inheriting classes and via accessors. On the smallest level this class deals
with generation of polygons and their specific drawing order based on alignment
and orientation.
Requirements:
Critical
requirements for this class to function are completed upon instantiation upon
an overloaded constructor which passes an array of the type CoordBlock to the
internals of the class where it is copied and used locally. Since points will
need to be generated for both the right and left sides of the line with a
specific draw order for each side operations on this list must be completed
twice for the same initial set of linear points. Z values of the Vertex3d
object within the class type CoordBlock are maintained while the application
itself does not account for them.
Polygon Draw Order:
To
manipulate points spatially and create a polygon that the system will draw
first a polygon must be broken up into its component triangles. These can be
oriented in any direction but there are best orders for generating serialized
polygons permitting both start and end points of the draw order to exist on the
same side of the polygon. In order for the system to properly draw an object
the points of that object must be order in series to the right of the last. For
example considering any point in a 2d coordinate system, to direct the next
point appropriately you must make a right turn to the next point and be able to
make another right turn in the direction of travel from the first point back to
the 3rd point. Situations in which this
criterion is not met will not draw correctly. In the case of serialized
triangles it is possible for one triangle to draw incorrectly without
destroying the others in the series.
Code Description:
Upon
instantiation via overload the array of points passed in is copied via loop and
used as to not damage the original array passed in by reference. The following
processes occur in two loops one for the right side of the array of points and
the second for the left side. The class instantiates a version of DoubleLinked
data storage type to hold the variable list of output points. Each item within
the original array and turned into 6 additional points placed in static order
to the list object. Once the points are aligned the list is copied and made
available for eternal access via accessor function which returns a list object
by reference.
2.3.10.1
- Sequence Diagram
2.3.10.2 – CRC
Class Properties:
CoordBlock* localCoordBlock
long size
float
surfaceZ
DoubleLinked<CoordBlock>
list
DoubleLinked<CoordBlock>
rightList
DoubleLinked<CoordBlock>
leftList
Method
Prototypes:
BuildDrawList(CoordBlock
(&coordArray)[N])
BuildDrawList(DoubleLinked<CoordBlock>
&list)
void SetSurfaceZ(float z)
void ClearList()
void CompletePolygonRight()
void CompletePolygonLeft()
void
CompleteVertexBlockRight(int i)
void
CompleteVertexBlockLeft(int i)
void
GetCoordBlock(DoubleLinked<CoordBlock> (&list2))
CoordBlock
CompleteCoordBlock(Vertex3d inputVertex)
Inheritance:
CalculateNormals
ParseVector
2.3.11 - EventLog
Purpose:
This class holds events created by the driving simulator. It efficiently stores car status data during
run time and generates an XML string when simulation is finished.
Requirements:
This class requires cstdlib, time.h, sstream, and cstring to
run. It also depends on EventNode, but
that definition is included in the same header file.
Code Description:
After creating the new object, the class creates a single linked
list of EventNode classes to hold all data.
Events are meant to be added in 500 millisecond intervals with
extraneous events added as needed. The
EventLog.checkUpdate function allows users to see if 500 milliseconds have
passed since the last update. If that is
the case, this function returns true.
This provides a simple way of checking if an event should be added, then
adding it if necessary through EventLog.addEvent.
The EventLog.addEvent function accepts the car’s position as three
separate float values, the current status code, the car’s angle, the collision
angle and the string of an object it is colliding with if they exist, the car’s
speed, and the current time in milliseconds since the program has started. This function will add an EventNode instance
to the EventLog’s internal linked list.
The EventLog.generateXMLString provides a way to create a human
readable XML string. This string can
then easily be written to any file. The
function uses a string stream to hold the format the data and then returns a
string as a result.
For debugging purposes, a human readable timer in the form of a
character array can be returned by calling EventLog.GetClockTime.
2.3.11.1 - Sequence Diagram
2.3.11.2 – CRC
Class Properties:
clock_t lastUpdate
clock_t currentRunTime
int hr
int min
int sec
EventNode *startEvent
EventNode *lastEvent
Method Prototypes:
EventLog()
char* GetClockTime()
void addEvent(float carPosX, float carPosY, float carPosZ, int
status, float carAngle, float collisionAngle, string collisionObject, float
speed, float time)
bool checkUpdate()
string generateXMLString()
~EventLog()
Inheritance:
None
2.3.12 – SimInit
Purpose:
This class contains the main functions for the driving simulator.
It controls crucial operations such as holding the points on the road, logging
the events, handling the movement and alignment of both the car and the camera,
calculating the distance of the car from the center line and creating a status
message based on that, and holding the starting point of the road and car.
Requirements:
Critical requirements for this class to function are all of the
items defined in headers.h.
Code Description:
Simit( ) initialized DarkGDK with the sync rate and type of window
which is borderless in this case, reads points from VectorPionts.txt, and then
opens MemBlock for writing. After
setting up points, it will call DrawIrregularPoly to draw the road. Init( )
draws the basic vehicle cube and positions it to the starting point, creates
the land, and calls code to draw the road, to draw the lines on the road, to
point the camera, and to set the controller. It also prints the welcome message
that is closed by the spacebar, prints status information to the screen, and
adds an event to the log if the appropriate amount of time has passed.
2.3.12.1 - Sequence
Diagram (figure on next page)
2.3.12.2 - CRC
Class Properties:
CoordBlock CoordArrayReal[56];
EventLog evts;
VehicleTools Car;
Vertex3d camera;
CarStatus status;
Vertex3d startPos;
ControlDeviceManager controlManager;
CheckList* controllerList;
char* memblockFileName;
DoubleLinked<CoordBlock> list;
bool displayText;
Method Prototypes:
SimInit()
void Init()
void SimLoop()
void NotesPopup()
void DebugPopup()
void Event Handler()
Inheritance:
None
2.3.13 – CarStatus
Purpose:
This class calculates the cars position from the median of the
road and the car’s status during the execution of the driving simulator. It calculates a code of 0 for Normal Status,
1 for Off Road, 2 for Across the Center Line, and 3 for Collision.
Requirements:
This class requires the Vertex3d class, DarkGDK libraries, and the
math.h header to run.
Code Description:
After creating the new object, the car’s status can be found using
CarStatus.LocateCar() by sending in the arguments of the car’s integer ID, the
road stored as a CoordBlock(), and the number of vertices in the road. This function does a for-loop and uses the
ClosestPointOnSegment() function to find the closest point on each line segment
to the car. The car’s status will be
based on the nearest point on the road.
The function will also calculate which side of the road the car is
on. The status will update based on the
side of the road the car is on and how far away the car is from the median.
CarStatus.distanceFormula() will provide the distance between two
points when given 2 separate Vertex structures.
CarStatus.distanceFromRoad(), CarStatus.roadStatus(), and
CarStatus.getClosestPoint() are public accessors.
For debugging purposes, a human readable output about the car can
be shown by calling CarStatus.displayStatus.
2.3.13.1 - Sequence Diagram
2.3.13.2 – CRC
Class Properties:
float distance
int status
Vertex3d closestPoint
Vertex3d carPos
Method Prototypes:
CarStatus()
void LocateCar(int objectid, CoordBlock roadCoord[], int
arrayLength()
float distanceFromRoad()
int roadStatus()
Vertex3d getClosestPoint()
void displayStatus()
Inheritance:
None
2.3.14 – TextOverlay
Purpose:
There is a need to display text as a 2d overlay for system
information and user messaging. To make the constant usage of text overlay
easier to manage this class maintains a screen position pointer that can be set
for a single block of text permitting other blocks of text to be positioned
relative to the first text without overlap. Auto positioning is enabled by
default but can be disabled to override relative positioning per line of text
if necessary. Offsets and margins can also be set and reset at any time during
the drawing of the text. Animated text can be achieved by adjusting relative
positioning per each draw cycle of the main program loop. This class is
expected to be used within the main drawing loop of a DarkGDK application.
Requirements:
Depends upon DarkGDK.h for access to 2d text control and drawing
Code Description:
This class effects a wrapper around some common 2d text functions
of DarkGDK and adds the ability to write blocks of text using relative
positioning for new lines or for text to be drawn to the right of a previous
line at some offset distance. Currently this is only function for items affixed
to the left margin or to the center of the screen. No options exist for
affixing text to the right margin although the implementation would be subtle
inversion of the calculation for left alignment. These functions are provided
by a single(1) traditional constructor which sets default values to all
properties; Three(3) methods which handle relative positioning and two(2)
overloaded methods to force absolute text position for special circumstances.
Properties are handled with eight(8) accessor methods which can provide text
and cursor position information while allowing the reconfiguration of class
properties during usage.
2.3.14.1 - Sequence Diagram
2.3.14.2 – CRC
Class Properties:
int vertPos
int hzonPos
char* textString
bool autoPos
int fontSize
int newLineSpace
int leftOffsetSpace
double offsetPercent
Method Prototypes:
TextOverlay()
char* GetLastText()
int GetLastPosition()
void SetVertPos(int pos)
void SetNewLineSpace(int space)
void SetOffsetPercent(double percent)
void SetAutoPos(bool autoPos)
void SetFontSize(int size)
void SetLeftOffsetSpace(int size)
void CenterText(char* text)
void LeftOffsetText(char* text)
void CenterText(char* text, int pos)
void LeftOffsetText(char* text, int pos)
void RightofCurrentText(char* text)
Inheritance:
None
2.4 -
Operating Environment
The St
Vincent Driving Simulator is designed to work under windows XP and Vista
compatible computers with a compatible DirectX video adapter.
2.5 -
User Environment
Standard
desktop platforms with a single monitor are supported. This single monitor can
be supplanted with any DirectX compatible video display device, i.e. projector.
2.6 -
Design/Implementation Constraints
At its
current state this simulator is a prototype to prove the viability of DarkGDK
as a platform for a larger simulator application. While external controllers
are generally implemented as proof of concept major operation is done via
keyboard controls. While keyboard use is acceptable during testing the final
application requires sole use of an external control appliance. The software
must also be compatible with simple computer systems that have only basic video
card support.
2.7 -
Assumptions and Dependencies
To allow
for realistic vehicle control it is expected that the user will have a 2-3/4
turn steering wheel controller, and either brake/gas or brake/clutch/gas
controls. Further detail can be obtained from (Section 4.1 - Vehicle).
3.1 -
User interfaces
For the
purposes described in section 2.2.1.1 only the most minimalistic level of
interface is applied to the project. To stay in line with suspension of
disbelief the only direct interface will be that of dash instruments that are
expected within a motor vehicle.
3.2 -
Hardware interfaces
Keyboard
The keyboard is the generic default control for testing the
simulators functions. It has fully implemented control over the simulation
during development and should be maintained as a backup in the event of
external controller failure.
Steering Wheel
This is the target method of interface with the simulator. Due to
the level of user immersion required for the simulators use as a clinical
testing aid. True to live control is required.
3.3 -
Software interfaces
An
external data viewer is included in this project although this interface is via
a data file generated at the end of each simulation.
4.1 -
Vehicle
4.1.1 - Shape
The shape of the vehicle is of a square in two-dimensional space
and of a cube in three-dimensional space. These two shapes will be created
based on the same given length for the distance between two adjacent points on
the side of either figure.
4.1.2 - Traveling Along Road
The vehicle will be pinned to the surface of the terrain in order
to have the vehicle stay on the terrain and not float off into space. The
z-coordinate of the vehicle and the vehicle’s current position on the terrain
is tracked. To pin the vehicle to the surface of the terrain, the vehicle will
always have the same z-coordinate value as the terrain at each location the
vehicle moves.
4.1.3 - Tracking
Tracking the position and condition of the vehicle is dynamic in
that there is a predetermined polling time for when the position and the
condition of the vehicle is recorded throughout the simulation. According to
these recordings, reports can be generated about significant events and the
overall performance during the simulation.
4.1.3.1 - Car Object Center
Position of the vehicle will be determined by a point at the
center of the vehicle. The point at the center of the vehicle is calculated by
drawing a diagonal from two opposite corners in the square and placing the
center point at the midpoint of the drawn diagonal.
4.1.3.2 - Driving Line
A margin distance will be determined and used to give the lane of
best driving a section along its two parallel outer edges. If the vehicle
enters this marginal area, then an event will be generated. The purpose of this
event is to indicate when the vehicle almost went off the road or into the
other lane. While the importance of this event is not as significant as
actually going off the road or into the other lane, it has an underlying
importance of indicating the details of how well the vehicle is being driven
within the lane of best driving.
To determine whether the vehicle is in the best driving lane, in
the oncoming traffic driving lane, or off the road, a perpendicular line from
the road vector line of a given length is created using normals. The vehicle is
one end point on this perpendicular line. Based on the location of the opposite
end point of the perpendicular line, the relative position of the vehicle can
be determined at any given time.
Deviation
Using the vector that created the road surface, another vector can
be formed for determining the center of the best driving lane by shifting the
original vector. This vector that determines the center of the best driving
lane can be compared to the vehicle vector to calculate the deviation from the
center of lane. Thus, the center of the lane vector lays out the best possible
path for the vehicle to travel during the simulation. Comparisons between these
two vectors will be made according to a specified time interval and the
deviation of the vehicle’s vector will be recorded. An additional benefit from
this center of the lane vector is that whenever it is found that the vehicle is
in the wrong lane or off the road, the center of the lane vector can be used to
calculate how far the vehicle has traveled away from its appropriate position
in the best driving lane.
4.1.3.3 - Car Angle
Relative
Along with the center point of the vehicle that determines the
position of the vehicle at any given time, there will be two other points
attached to the vehicle, one at the front and one at the back of the vehicle.
These two points will be used to calculate a vector which can be used to
determine the angle or direction of the vehicle on the terrain. To find the
relative vehicle angle, compare the vector of the vehicle against the slope of
the closest road segment. To find the absolute vehicle angle, compare the
vector of the vehicle against the x- and y-coordinate axes of the terrain.
Absolute
This angle is provided directly by DarkGDK
Figure
4.1.3.4 - Collision/Bounding
Road Lines
The vehicle will have four points indicating the vehicle’s edges
on each side. These four points will be located on the four corners of the
vehicle. The purpose of these points is in future implementations to indicate
if any part of the vehicle collided with another object. This is significant
because the current method uses only the center point of the vehicle which
could overlook pertinent collision events.
Repositioning
If the vehicle experiences a severe collision or a collision where
moving afterwards is impossible, the vehicle will be reposition onto the road.
The repositioning will be to the center of the driving lane across from the
area of the collision. If the collision is extremely severe, say colliding with
another vehicle head on, the simulation ends to replicate reality since after
such a collision the vehicle would be totaled and not drivable. If the vehicle moves in the opposite
direction necessary to complete the simulation for an “x” amount of time, then
the vehicle will be repositioned to face the correct direction in the center of
the driving lane across from the last recorded position of the vehicle. If the
vehicle would happen to go the wrong direction and approach the vehicle’s
starting position, once the vehicle reached the starting position, the vehicle
would be stopped and repositioned to face the correct direction at the starting
position. If the vehicle ventured of the road and into the terrain for an “x”
amount of time, then the vehicle would be repositioned to the center of the
best driving lane across from the last recorded position of the vehicle on the
terrain. Repositioning should be more or less infrequent and the result of
great misbehavior on the drivers part because reposition is not realistic. The
time “x” mentioned above should be a long period of time in order to eliminate
minor mistakes from triggering repositioning and to leave only blatant
misbehavior by the driver to cause repositioning. Also if the terrain contains
non-drivable areas such as bodies of water or cliffs and the vehicle drives
into these areas, the vehicle will be repositioned as before to the best
driving lane across from the last position recorded on the drivable terrain.
4.1.3.5 - Collidable Object Proximity
All objects that have the potential of being collided into have a
sensorial field surrounding them of a given radius. The purpose of this
sensorial field is that if the vehicle ever enters this field a collision event
is generated and recorded. It is important to set a reasonable sized radius for
the sensorial field of objects because if the field is too small or large,
events would be left out or unnecessarily generated. This sensorial field will
be generated by drawing an invisible circle on the terrain around the
collidable object according to the specified radius. This area on the terrain
will be checked on a specified time interval to see if the vehicle has entered
the area.
4.1.3.6 - Criteria
Distance
Calculate the distance the vehicle has traveled by after each time
interval when the position of the vehicle is recorded use the distance formula
to determine the distance between the newly recorded position and the next to
last position recorded. The vehicle’s distance will be stored globally for use
throughout the program. This distance value will begin at zero at the start of
the simulation and as the vehicle moves, the incremental distances calculated
after each time interval will be added to global distance value. The distance
value is always positive even if the vehicle moves backwards.
Speed
Calculate the speed of the vehicle based on the distance traveled
and the elapsed time. To complete this calculation use the vehicle’s distance
value and simulation’s clock. The speed of the vehicle is recorded after the
given time interval when the position of the vehicle is updated and recorded.
Speed Change
Apply deceleration to the vehicle when going up an incline and
acceleration to the vehicle when going down an incline. The rate of
acceleration and deceleration will be determined based upon the calculation of
the angle between the directional vector of the vehicle and a level line on the
terrain. Acceleration and deceleration can be distinguished between based upon
the location of the directional vector when placing the directional vector in a
two-dimensional graph with the directional vector point at the back of the
vehicle at the origin. If the direction vector is graphed in the first or
second quadrants, then deceleration will be applied to the vehicle. If the
directional vector is graphed in the third or fourth quadrants, then
acceleration will be applied to the vehicle.
Acceleration
When the vehicle is at rest, allow the vehicle to accelerate to
have a drivable speed. Have a max speed that the vehicle cannot exceed in order
to avoid continuous acceleration and thus extreme speeds. This can be
accomplished with a checking of the condition of the vehicle: if the vehicle is
at rest, allow the vehicle to accelerate; or if the vehicle is at a speed below
the maximum speed allowed, allow the vehicle to accelerate. The rate of
acceleration should be dependent on the level at which the accelerator is being
pressed in at a given moment.
Deceleration
When the vehicle is in motion, allow the vehicle to decelerate to
a stop instead of coming to a drastic stop in the mist of just moving or
continuing at a constant speed. This can be accomplished with a checking of the
condition of the vehicle: if the vehicle is in motion and if the breaks are
being hit, allow the vehicle to decelerate; or if the vehicle is in motion and
if neither the accelerator nor break are being pressed, allow the vehicle to
decelerate; or if the accelerator and the break are being pressed simultaneously
but the break is being pressed in more so than the accelerator, allow the
vehicle to decelerate. The deceleration of the vehicle whenever the break is
pressed should be the greatest of the decelerations. The rate of deceleration
of the vehicle when dependent on the break should be calculated based on the
level at which the break is being pressed in at a given moment. The
deceleration of the vehicle whenever neither petal is pushed should be a slight
deceleration to allow the vehicle to roll to a stop gently. The most complicated deceleration will be
when both petals are being pressed. In this case the rate of deceleration
provided by the pressing of the brake is subtracted from the rate of
acceleration provided by the pressing of the accelerator. (Reminder: The rate
of deceleration is a positive value in this instance.)
4.1.4 - Turning Angle and Rate
The turning of the vehicle will be determined by taking into
consideration the pivot point of the vehicle and the steering rotational input
from the steering wheel controller to provide a realistic turn.
Calculation
As speed increase, the turning radius of the vehicle will
decrease. Thus when the vehicle is driven as high speeds, making sharp turns
will not be possible as in reality. Calculating this decrease of turning radius
involves taking fractions of the turning radius established as the base turning
radius for slow speeds. Once the vehicle’s speed exceeds the threshold for slow
speeds, fractions will be multiplied to the base turning radius to provide the
new turning radius. The fractions are determined by calculating the numerator
as the maximum speed minus the current speed and the denominator as the maximum
speed.
4.1.4 - Steering
Pivoting
To
give the driving of the vehicle a more realistic feeling, the vehicle will
pivot around the center of the back wheels (or toward the back of the vehicle)
when turning.
Interface
A camera is attached to the vehicle so that the camera is
positioned inside the vehicle at the approximate position that the driver would
be seated. This means the camera should be position toward the left side of the
vehicle and about three feet from the windshield. In the camera’s view there
should be the windshield, the dashboard with rudimentary gages, and a slight
view of the hood of the vehicle. The main measurement that the gages should
display are the speed of the vehicle and time elapsed driving in the
simulation, like a clock on the dashboard but instead of a clock it is a timer.
In addition, the dashboard should also have a signal that displays informing
the driver when a collision has occurred. This signal will be beneficial to the
driver whenever a collision occurs that is not head on or toward the front of
the vehicle. All of this information will encompass the basic interface seen on
the screen during the driving simulation.
4.2 - Environment
4.2.1 - Ground
4.2.1.1 - Road Surface Matching
Ground beyond the road surface is created by texturing a height
map. In the current implementation of the project this surface has a height
value set to but independent of the road height. To make this height map match
the road surface it is necessary to seek out the closest point to the road edge
that corresponds to the height of the road. Once this point is located it can
be set to the height of the road. The general rule is that no change in height
can be more than 20 degrees from the last 3 road sections. By avoiding huge
rapid changes in terrain the likelihood of there being difficulty matching
terrain height should be minimized.
Terrain Depth
To provide a smaller margin for error when matching terrain to the
road height a minimum depth of the terrain height map is double the number of
segments of the road over the same distance of the road. Thus, if the road has
a width of 100 units and 5 road segments within that width, each segment must
account for at least 20 units of distance thus the height maps width must have
10 segments per 100 width thus permitting 10 units of distance per terrain
segment. The same will be true for the length of the road along the other axis.
This will not be an absolutely accurate mechanism for calculating road segments
because it does not incorporate the amount of segment length lost from varied
height and turns. This will not be much concern since none of the road segments
or terrain points will match up correctly exactly.
Finding Road Dimensions
To calculate the segment bounds of the road surface the mesh must
be disassembled to find the max and min of each cardinal direction. From these
points the rectangular bounds of the region is possible.
4.2.1.2 - Infinite Terrain
Outside the range of the height map planes will be tiled from to
create a simple to draw series of regions which will be "infinite" in
distance. By "infinite" the dimensions will be of such a size as to
make it improbable for a user to reach the end without being completely outside
the bounds of expected testing.
4.2.2 - Skybox/Skysphere
The skybox and skysphere is the effective horizon that sits at an
infinite distance from the camera. This permits the usage of multiple backgrounds
to represent multiple environments.
4.3 -
Road
4.3.1 - Road Creation
4.3.1.1 - Generation of Road Path
Static Vector(i)
Vector Creation
To create a static vector that will not create polygons that
overlap the distance between each adjacent set of points must be greater than
or equal to the distance defined for the distance of the normal point from the
line define by the two adjacent points from the original point. The process to
easily create these points by hand is to draw a circle whose center is any
point and whose radius is the set distance between points. Thus by selecting
any point on the circle the distance will be correct.
Normal Calculation
The calculation will take in 3 sequential vector points. With a
line drawn from the first and last points of the 3 we can find an estimated
normal of the middle point. by using this slope of the normal we can plot a new
point to the right and left of the middle point. These normal points become the
basis for a polygon on each side of the initial vector line.
Vector Drawing Tool
While creating of a vector by hand is not a complex process. For
testing there needs to be a program to generate a point at a static distance
from another point at any angle. From this tool a compatible vector list will
be output ready for testing.
4.3.1.2 - Generation of Road Mesh(i)
The surface that is to be displayed as the visual road will be
generated by expanding a single vector into a series of polygons. This will
permit variations in direction and in height when implemented. This surface
will be created as a single mesh from a single vector or a composite of similar
smaller meshes. Goals behind road generation are to permit the storage of
absolute positioning within the object itself. At any time a mesh may be
positioned and its bounds can be extracted.
Creating MemBlock(i)
MemBlocks are a binary access data storage method that allows a
block of physical memory to be directly written to and read from active memory.
While the process does not actually allow for manipulation of active memory the
effect is the same. Through the use of DarkGDK it is possible to create MemBlocks
of binary files used by the DirectX renderer DirectDraw. Once created a MemBlock
may also be saved to a binary file for later use. Through this process once a
road is generated it does not have to be regenerated each time while allowing
for persistence of original vector information by reading and reorganizing the
data from a MemBlock.
Drawing Mesh(i)
The DirectX renderer, Direct Draw permits the drawing of
sequential points to form a mesh. In these circumstances draw order is very
specific. From any point the next successive point must be drawn to the right
of the last. This is the result of positive angles are calculated from the left
side in a clockwise direction towards the next line segment. If an angle is negative
or turns to the left from the previous point then the line is culled.
In the process used to draw sequential polygons it is imperative
to start from the smallest primitive to be drawn, the triangle. From this a
larger polygon is constructed. In the case of road generation the maximum unit
is a 4 sided polygon repeated. This drawing order is specific to the direction
and relative angle of the road segment.
Flexible Vertex Format
This format is not DirectX specific but does allow DirectX renders
to read point information and maintain vertex information including normal
values, uv coordinates, and diffuse color.
Example of FVF 338 in Dark GDK
Please see Section 2.3.5 – DrawIrregularPoly
Advice
about data types
When
writing or reading a MemBlock the position is relative to 1 byte each position
that you can access is 1byte so a Dword or Double word is the same length as an
uint32 (32 bit unsigned integer). Thus to not overwrite data within the MemBlock
it is necessary to allow for the right amount of space before proceeding.
As in the example below each line movies the MemBlock position by 4 bytes or 32
bits. The smallest amount of information is 1byte and the largest is a Dword.
Advice
about MemBlock sizes. This is easy to derive mathematically. For a 338 by 36
bit vertex FVF we can calculate the size of the MemBlock by taking the header
which is
[96bit
+ ( Number of Vertices x ( 3 x 96bit)] / 8bit
The
break down is that the header is 96 bit and each vertex coordinate, normals coordinate,
and diffuse color / uv coordinate is 96 bit each so we have 288bits for each
vertex multiplied by the number of vertices plus the header. Now we have the
raw bits of the MemBlock divide by 8 to get the number of bytes.
Code
to Generate above MemBlock
This
MemBlock will create the same thing that dbMakeObjectPlain(1,10,10);
Of
course this method allows up to make irregular planes. I will write a class
around this to make created the planes as easy as giving 4 coordinates.
a
= 0;
//Custom Mesh Dynamically
//Header
dbMakeMemblock(2,
228);
dbWriteMemblockDword(2,a=a,338);
dbWriteMemblockDword(2,a=a+4,36);
dbWriteMemblockDword(2,a=a+4,6);
//First Cord
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,5);
//Second Cords
dbWriteMemblockFloat(2,a=a+4,-2);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,-5);
//Third Cords
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,-5);
//Fourth Cords
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,5);
//Fifth Cords
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,5);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,-5);
//Sixth Cords
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
// Normals
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,-5);
dbWriteMemblockFloat(2,a=a+4,0);
//Difusion Color
dbWriteMemblockDword(2,a=a+4,1065353216);
//UV Cords
dbWriteMemblockFloat(2,a=a+4,0);
dbWriteMemblockFloat(2,a=a+4,-5);
Drawing Complex Objects
For the current system to create a road surface a single linear
vector must be defined but this does not permit the rendering of complex road
surfaces like intersections or Y's in the road. The current linear drawing
method can be adapted to support complex and branched surfaces. The current
method draws the right side of the road surface and then the left side of the
road surface. This can be applied if the drawing can track the right side of a
complex vector by identifying an additional point at each dead end.
In this figure we see what the system would have to account for
when it reached a dead end.
In the case of a loop it is necessary to detect if a polygon
already exists within the range of the normal distance to the next set of
points. This will assure that system does not redraw overtop of already drawn
surface areas.
Saving Mesh(i)
By considering meshes as synonymous with MemBlocks to save a mesh
using DarkGDK consists of converting it to a MemBlock and then saving that MemBlock
to a file. Although this file is not human readable it can be directly loaded
back into the environment at any time.
Mesh Manipulation
Since meshes and MemBlocks are synonymous we can treat a mesh as
sequenced data in a MemBlock. Currently implemented is a MemBlock parser which
will return the sequential data of the MemBlock. This data is a series of
Coordblocks which contains all of the vertex data, normals, and diffuse
information about the object. To manipulate a mesh by moving it we can affect a
change in xyz distance across all points and the resulting MemBlock will be
shifted by those values when redrawn. The same is true for sequential growth in
height across the surface. If a surface's coordinates are extracted and
manipulated lateral tilts can also be created.
Mesh Parsing
4.3.1.3 - Bounding and Collision
Bounding by Distance Calculation(i)
While bounding by collision is possible using the same mechanism
used by road and road line generation to create regions about the road surface
as a single object for collision tracking, but since bounding is being managed
based upon a simple range from the road surface this is not needed.
4.3.1.4 - Texturing
Road Lines
While the road surface is a complex object which contains
texturable uv information it is easier to take the same road information to
generate additional object segments that represent the road lines both yellow
and white on the road. In the future these additional road line objects can be
used to better validate the vehicles position on the road and provide enhanced
collision detection.
4.4 -
Events
4.4.1 - Data
4.4.1.1 - Static
Start Position
Timing
Start
The starting time of the event will be based off of when the
simulation starts. For example, the
event will start 20 seconds from the start of the simulation.
Stop
The stopping time of the event will be relative to the starting
time. For example, one may only last
until 25 seconds and will then go out of sight.
Result
The result of an event will depend on the type of event. If the car hits a tree, then it will display
that it has crashed and the car will reset on the road. If the car hits an object such as a
pedestrian, then the car will not come to a complete stop like when striking a
tree, it will keep moving.
4.4.1.2 - Dynamic
Event Trigger
Location Triggered
After the car reaches a certain point on the road, it will trigger
an event or sequences of events.
Event that Triggered
Depending on prior events, new events or event sequences will be
created.
Timing
Start
Starting time will be either immediate after a location or event
trigger or it will start a certain time after.
Stop
Stopping time varies per event and will be relative to the
starting time.
Result
The result of an event will depend on the type of event. If the car hits a tree, then it will display
that it has crashed and the car will reset on the road. If the car hits an object such as a
pedestrian, then the car will not come to a complete stop like when striking a
tree, it will keep moving.
4.4.2 - Event Sequencing
4.4.2.1 - Predefined Event Sequence
Once the car reaches a certain point on the road, it may trigger
an event sequence such as the proceeding example. Ball on road 20 feet ahead and the event will
be triggered when the bounding box of the car collides with the bounding box of
the ball, pedestrian walks across road 200 feet ahead and the event will be
triggered when the bounding box of the car collides with the bounding box of
the pedestrian, car in current lane 300 feet ahead and the event will be
triggered when the bounding box of the car collides with the bounding box of
the other car, car in opposite lane 400 feet ahead and the event will be
triggered when the bounding box of the car collides with the bounding box of
the other car, and car in opposite lane 450 feet ahead and the event will be
triggered when the bounding box of the car collides with the bounding box of
the other car.
4.4.2.2 - Random Event Sequences
To keep the test studies more accurate, a random event sequence generator
may be included. This random sequence
will ensure duplicate participants will not have a better chance of driving
without error on the simulator. It will
also ensure that previous participants cannot tell others about when events
will occur.
4.4.3 - Simultaneous Events
Events occurring at the same time will need to be accounted
for. For example, the event that a car
is off of the road and the event that a car has struck a tree will be
simultaneously occurring. These will be
reported in the order of what has been previously occurring. In this case, the event off the road will be
reported first and then the event that the car has struck an object,
specifically a tree, will be reported immediately following. If they occur precisely at the same time,
then the extraneous event gets precedence.
4.4.4 - Event Types
0 - Normal
1 - Off Road
2 - Cross Center Line
3 - Collision with Object
~ - Vehicle Reset
~ - Reaction Status
4.5 -
Collision
4.5.1 - Driving
4.5.1.1 - Tracking Event Sequence
The collision is recorded.
The collision event can occur with any angle of the vehicle.
The speed and angle of the vehicle at the time of the collision
will be recorded. The data that is
recorded will be used to determine the severity of the collision with the
object.
4.5.1.2 - Collision Data
4.5.2 - Collision Tracking
Location
During the simulation there will be a list of event types of the
vehicle that can be viewed in section events->list of event types. The location will be recorded by using a flag
to place at the spot of the collision and will be outputted to see after the
simulator is done. If a collision with
an object occurs out of the designated driving lane for the vehicle, that event
will be recorded first followed by a record of the collision with the object.
Speed
The speed of the vehicle at the time of the collision will also be
recorded. The speed of the vehicle is
visible at the top of the screen during the simulator so the user will know the
current speed at all times. As soon as
the vehicle collides with another object, the current speed of the vehicle at
the time of impact will be recorded and placed in the output.
Angle
The angle of the vehicle during the collision will be documented
using the record of the last recorded vector vs. the horizon of the object that
it collided with. The angle and speed of
a collision determine the severity of the collision. If the angle of the collision with an object
creates enough damage that the vehicle is not drivable, the vehicle will be
repositioned on the road in the correct lane.
The main collisions that would prevent the vehicle from being drivable
would be: a collision to the left or right front of the vehicle which would
ruin one of the tires or a collision head on that would ruin the engine. The simulation will continue as long as the
vehicle is still drivable.
Duration
Some collisions may last longer than others, so the duration of
the collision will also be recorded.
Severe collisions with the vehicle may only take a second depending on
the damage of the vehicle. If the
vehicle is not drivable, it will be immediately placed back on the road. If the collision is not so severe, the time
that the vehicle is colliding with another object will be recorded. If the collision is very severe, the
simulation will end to replicate reality.
Please see section vehicle->repositioning.
4.5.3 - Repositioning
If the vehicle experiences a severe collision or a collision where
moving afterwards is impossible, the vehicle will be reposition onto the road. The repositioning will be to the center of
the right driving lane across from the area of the collision. If the collision is extremely severe, for
example, colliding with another vehicle head on, the simulation ends to
replicate reality since after such a collision the vehicle would be totaled and
not drivable.
4.5.4 - Reporting Results
All of the collisions will be recorded and placed into an output
document. There will be a list of all
the collisions that occurred during the simulation, along with the all the
factors contributed to the collision. In
the document, there will be a record stating if the collision occurred at an
event or at a random place on the course.
4.6 -
Data Management
The
information under these subheadings is important pieces of information that
apply to the project. The first
subheading includes data that should be eventually stored in the project. Currently the event log class does not keep
this information, but it will be smart to have in later iterations. The second subheading includes information
that is currently handled and stored by the event log.
4.6.1 - Data Classification
The information under these subheadings is important pieces of
information that apply to the project.
The first subheading includes data that should be eventually stored in
the project. Currently the event log
class does not keep this information, but it will be smart to the have in later
iterations. The second subheading
includes information that is currently handled and stored by the event log.
4.6.1.1 - Test Criteria
Participant Name
Overseer Name
Group
Sequence
Number
Date
4.6.1.2 - Simulation Criteria
Start Time
The start time in milliseconds will be the time of the first event
in the event log. This is tracked by the
milliseconds since the program started.
End Time
The end time in milliseconds will be the time of the last event in
the event log. This is tracked by the
milliseconds since the program started.
Vehicle Status
Position
The vehicle’s position, calculated from the global coordinates,
will give us information about the car in relation to the road. This is another necessity to generate any
meaningful reports.
Relative to Road Center
Relative to Start and End
Angle
Relative to Colliding Object
By taking the difference between the car’s global angle and the
colliding object’s global angle, the severity of the crash may be
estimated. An example graph is included
below. Some angles may need to be
regulated by adding or subtracting 90 until a value between 0 and 90 is reached.
Global
The vehicle’s angle is an important piece of data to see if the
car is going the correct direction on the road.
This is tracked by the object’s stored global angle.
Speed
Another important part about the car is the current speed it is
traveling. It is calculated by the
amount of displacement the car moves each cycle.
Distance from Center Line
The distance from the center line is calculated using a function
to find the nearest point on the road compared to the car and then using the distance
formula.
4.6.2 - Data Storage
During the simulation, the data is stored in an event log class
that is a linked list of event nodes.
Each node holds the needed information.
4.6.2.1 - XML
At the end of simulation, the event log class has the ability to
generate an XML data string.
4.6.2.2 - Aggregation Rate
Event data will be added every half second as long as the vehicle
does not collide with any objects. As we implement collisions, we can allow the
collision event to add extra event data to our log.
Data Growth Rate
Report Size
The current XML document allows the storage of approximately one
thousand events in a one megabyte file.
This allows 8 minutes of data to be tracked in a one megabyte file.
4.7 -
Reports
4.7.1 - During Simulation
When the program begins, in the center of the screen, instructions
on how to use the program are displayed.
Pressing the spacebar will clear out the message. The message informs the user that the arrow
keys control the vehicle, the return key resets the vehicle’s position, and the
tab key shows debug information.
4.7.1.1 - Real Time Reporting
On the upper left of the screen, during program execution,
information is displayed. The vehicle
id, the vehicle’s xyz coordinates, the vehicle’s angle, the velocity of the
vehicle, the running time of the program, and the car’s relative position to
the road.
Relative Distance from Road Center
The car’s position on the road is displayed in the upper left-hand
corner of the screen. This message
displays if the user is in the correct lane, the wrong lane, or if the user is
off the road. Also, the distance the
user is from the center line is displayed.
4.7.1.2 - End User Instructions
When the program begins, in the center of the screen, instructions
on how to use the program are displayed.
Pressing the spacebar will clear out the message. The message informs the user that the arrow
keys control the vehicle, the return key resets the vehicle’s position, and the
tab key shows debug information.
4.7.2 - Post Simulation
4.7.2.1 - Format
As the program is running, it will be compiling statistics on the
user’s driving that will be outputting as XML at the end of program
execution. Items that will be recorded
are the vehicle’s position, speed, status, angle, collisions, and the times
that these events occurred. This
information about the vehicle will be reported in 1 second intervals.
4.7.2.2 - Graphs
After program execution, a graph will be created showing the user
their deviation from the best driving line.
The x-axis will represent the time and the y-axis will represent the
deviation. In the center of the y-axis
will be 0, which is the best driving line.
Positive y values will represent deviations to the left while negative y
values will represent deviations to the right.
At times when there are obstacles to avoid, those periods of time will
be highlighted on the graph so the user will know if they attempted to steer
away from an impending collision.
Example
4.7.2.3 - Summary Report
After the graph is created, a summary report of the information
displayed on the graph will be created.
This report will include the events, the average deviation, the max
deviation, the distances from the events, collisions, and the time spent in the
wrong lane and off road.
Example
4.7.2.4 - Collision Report
A collision report will be generated after program execution. This report will list all events that
occurred that the user would need to adjust their driving trajectory to avoid a
collision. The times of these events
will be listed as well as if the user avoided the collision. If the user did collide with the object, the
speed and angle of collision will be recorded and displayed.
Example
5.1
Performance requirements
Dark GDK requires
Microsoft's Visual C++ 2008 Express compiler.
Minimum:
Pentium
III 1GHz or equivalent
Windows
XP (Home/Pro) / Vista
1 GB of
hard disk space
512 MB of
Ram
Fully
DirectX compatible Graphics Card with 128 MB Memory or more and Hardware 3D
Acceleration
DirectX
compatible Sound Card
We
recommend your video card has at least 256 MB of memory to get the most from
the Dark GDK. You will otherwise be limited in the size of game and type of
effects you can use. Certain features of the Dark GDK (such as vertex / pixel
shaders) require a suitably powerful graphics card. Please check with your
video card manufacturer before purchasing.
Recommended
Dual Core
1.8GHz or above
Windows
XP (Home/Pro) / Vista
1 GB of
hard disk space
1 GB of
Ram
Fully
DirectX compatible Graphics Card with 256 MB Memory or more and Hardware 3D
Acceleration
Direct X
compatible Sound Card
5.2
Safety requirements
Photosensitive Seizure Warning
A very small percentage of people may experience a seizure when
exposed to certain visual images, including flashing lights or patterns that
may appear in video games. Even people who have no history of seizures or
epilepsy may have an undiagnosed condition that can cause these
"photosensitive epileptic seizures" while watching video games.
These seizures may have a variety of symptoms, including
lightheadedness, altered vision, eye or face twitching, jerking or shaking of
arms or legs, disorientation, confusion, or momentary loss of awareness.
Seizures may also cause loss of consciousness or convulsions that can lead to
injury from falling down or striking nearby objects.
Immediately stop playing and consult a doctor if you experience
any of these symptoms. Parents should watch for or ask their children about the
above symptoms - children and teenagers are more likely than adults to
experience these seizures.
The risk of photosensitive epileptic seizures may be reduced by
taking the following precautions:
* Play in a well-lit
room
* Do not play when you
are drowsy or fatigued
If you or any of your relatives have a history of seizures or
epilepsy, consult a doctor before playing.
6.1 - Appendix
A: Terminology/Glossary/Definitions list
collision. the act of (a) vertex(s) passing through the
space defined by the vertexes of another object.
collision
box. Bounding Box - defined region of
space that generally has no visible components but can be collided with.
object
culling. Making an object's mesh and
its texture not visible. Generally a culled object may still have a physical
effect on other objects
object. The combination of vertices to create a mesh
that can be drawn into a visible entity within a 3D environment.
camera. The Field of View within a 3D environment
sky
box. A standard cube object that is
drawn inverted as to allow for the inside of the cube to be visible. This cube
also exists at an "infinite" relative distance from the camera.
mesh. The set of vertices, UV Coordinates, and
Normals Coordinates that make up an object.
texture. A bicubic image wrapped around a wireframe
object with relative position matched to the uv coordinates defined by.
uv. Static per vertex coordinates for mapping
distance between texture points.
normal.math. Perpendicular point to a line generally in 2
dimensions.
normal.textures. Perpendicular point to a surface generally
in 3 dimensions
MemBlock. Raw binary representation of an object i.e.
a mesh
vertex. Set of spatial coordinated representing the
location of a point within the 3D environment.
draw
order. In different 3D systems this can
vary but it defines in which direction an object must be drawn for it to be
visible. Generally a mesh only shows 1 face all other faces are
transparent.
e.g. A Triangle has a top face and an underside face. Depending on the order
the vertices are aligned defines which face is textured.
vector.data
structure. An arbitrary sized array
data storage structure implemented in the C++ STL.
vector.usage. A linear list of 3 dimensional points that
are used to define the height and direction of a linear surface.
6.2 - Appendix
B: License
Creative
Commons Attribution-Share Alike 3.0 United States
CREATIVE
COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES.
DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP.
CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND
DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
License
THE WORK
(AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC
LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT
AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER
THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY
EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE
BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE
CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE
IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1.
Definitions
"Collective
Work" means a work, such as a periodical issue, anthology or encyclopedia,
in which the Work in its entirety in unmodified form, along with one or more
other contributions, constituting separate and independent works in themselves,
are assembled into a collective whole. A work that constitutes a Collective Work
will not be considered a Derivative Work (as defined below) for the purposes of
this License.
"Creative
Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being
essentially equivalent to this License, including, at a minimum, because that
license: (i) contains terms that have the same purpose, meaning and effect as
the License Elements of this License; and, (ii) explicitly permits the
relicensing of derivatives of works made available under that license under
this License or either a Creative Commons unported license or a Creative
Commons jurisdiction license with the same License Elements as this License.
"Derivative
Work" means a work based upon the Work or upon the Work and other
pre-existing works, such as a translation, musical arrangement, dramatization,
fictionalization, motion picture version, sound recording, art reproduction,
abridgment, condensation, or any other form in which the Work may be recast,
transformed, or adapted, except that a work that constitutes a Collective Work
will not be considered a Derivative Work for the purpose of this License. For
the avoidance of doubt, where the Work is a musical composition or sound
recording, the synchronization of the Work in timed-relation with a moving
image ("synching") will be considered a Derivative Work for the
purpose of this License.
"License
Elements" means the following high-level license attributes as selected by
Licensor and indicated in the title of this License: Attribution, ShareAlike.
"Licensor"
means the individual, individuals, entity or entities that offers the Work
under the terms of this License.
"Original
Author" means the individual, individuals, entity or entities who created
the Work.
"Work"
means the copyrightable work of authorship offered under the terms of this
License.
"You"
means an individual or entity exercising rights under this License who has not
previously violated the terms of this License with respect to the Work, or who
has received express permission from the Licensor to exercise rights under this
License despite a previous violation.
2. Fair
Use Rights. Nothing in this license is intended to reduce, limit, or restrict
any rights arising from fair use, first sale or other limitations on the
exclusive rights of the copyright owner under copyright law or other applicable
laws.
3.
License Grant. Subject to the terms and conditions of this License, Licensor
hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
duration of the applicable copyright) license to exercise the rights in the
Work as stated below:
to
reproduce the Work, to incorporate the Work into one or more Collective Works,
and to reproduce the Work as incorporated in the Collective Works;
to create
and reproduce Derivative Works provided that any such Derivative Work,
including any translation in any medium, takes reasonable steps to clearly
label, demarcate or otherwise identify that changes were made to the original
Work. For example, a translation could be marked "The original work was
translated from English to Spanish," or a modification could indicate
"The original work has been modified.";
to
distribute copies or phonorecords of, display publicly, perform publicly, and
perform publicly by means of a digital audio transmission the Work including as
incorporated in Collective Works;
to
distribute copies or phonorecords of, display publicly, perform publicly, and
perform publicly by means of a digital audio transmission Derivative Works.
For the
avoidance of doubt, where the Work is a musical composition:
Performance
Royalties Under Blanket Licenses. Licensor waives the exclusive right to
collect, whether individually or, in the event that Licensor is a member of a
performance rights society (e.g. ASCAP, BMI, SESAC), via that society,
royalties for the public performance or public digital performance (e.g.
webcast) of the Work.
Mechanical
Rights and Statutory Royalties. Licensor waives the exclusive right to collect,
whether individually or via a music rights agency or designated agent (e.g.
Harry Fox Agency), royalties for any phonorecord You create from the Work
("cover version") and distribute, subject to the compulsory license
created by 17 USC Section 115 of the US Copyright Act (or the equivalent in
other jurisdictions).
Webcasting
Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a
sound recording, Licensor waives the exclusive right to collect, whether
individually or via a performance-rights society (e.g. SoundExchange),
royalties for the public digital performance (e.g. webcast) of the Work,
subject to the compulsory license created by 17 USC Section 114 of the US
Copyright Act (or the equivalent in other jurisdictions).
The above
rights may be exercised in all media and formats whether now known or hereafter
devised. The above rights include the right to make such modifications as are
technically necessary to exercise the rights in other media and formats. All
rights not expressly granted by Licensor are hereby reserved.
4.
Restrictions. The license granted in Section 3 above is expressly made subject
to and limited by the following restrictions:
You may
distribute, publicly display, publicly perform, or publicly digitally perform
the Work only under the terms of this License, and You must include a copy of,
or the Uniform Resource Identifier for, this License with every copy or
phonorecord of the Work You distribute, publicly display, publicly perform, or
publicly digitally perform. You may not offer or impose any terms on the Work
that restrict the terms of this License or the ability of a recipient of the
Work to exercise of the rights granted to that recipient under the terms of the
License. You may not sublicense the Work. You must keep intact all notices that
refer to this License and to the disclaimer of warranties. When You distribute,
publicly display, publicly perform, or publicly digitally perform the Work, You
may not impose any technological measures on the Work that restrict the ability
of a recipient of the Work from You to exercise of the rights granted to that
recipient under the terms of the License. This Section 4(a) applies to the Work
as incorporated in a Collective Work, but this does not require the Collective
Work apart from the Work itself to be made subject to the terms of this
License. If You create a Collective Work, upon notice from any Licensor You
must, to the extent practicable, remove from the Collective Work any credit as
required by Section 4(c), as requested. If You create a Derivative Work, upon
notice from any Licensor You must, to the extent practicable, remove from the
Derivative Work any credit as required by Section 4(c), as requested.
You may
distribute, publicly display, publicly perform, or publicly digitally perform a
Derivative Work only under: (i) the terms of this License; (ii) a later version
of this License with the same License Elements as this License; (iii) either
the Creative Commons (Unported) license or a Creative Commons jurisdiction
license (either this or a later license version) that contains the same License
Elements as this License (e.g. Attribution-ShareAlike 3.0 (Unported)); (iv) a
Creative Commons Compatible License. If you license the Derivative Work under
one of the licenses mentioned in (iv), you must comply with the terms of that
license. If you license the Derivative Work under the terms of any of the
licenses mentioned in (i), (ii) or (iii) (the "Applicable License"),
you must comply with the terms of the Applicable License generally and with the
following provisions: (I) You must include a copy of, or the Uniform Resource
Identifier for, the Applicable License with every copy or phonorecord of each
Derivative Work You distribute, publicly display, publicly perform, or publicly
digitally perform; (II) You may not offer or impose any terms on the Derivative
Works that restrict the terms of the Applicable License or the ability of a
recipient of the Work to exercise the rights granted to that recipient under
the terms of the Applicable License; (III) You must keep intact all notices
that refer to the Applicable License and to the disclaimer of warranties; and,
(IV) when You distribute, publicly display, publicly perform, or publicly
digitally perform the Work, You may not impose any technological measures on
the Derivative Work that restrict the ability of a recipient of the Derivative
Work from You to exercise the rights granted to that recipient under the terms
of the Applicable License. This Section 4(b) applies to the Derivative Work as
incorporated in a Collective Work, but this does not require the Collective
Work apart from the Derivative Work itself to be made subject to the terms of
the Applicable License.
If You
distribute, publicly display, publicly perform, or publicly digitally perform
the Work (as defined in Section 1 above) or any Derivative Works (as defined in
Section 1 above) or Collective Works (as defined in Section 1 above), You must,
unless a request has been made pursuant to Section 4(a), keep intact all
copyright notices for the Work and provide, reasonable to the medium or means
You are utilizing: (i) the name of the Original Author (or pseudonym, if
applicable) if supplied, and/or (ii) if the Original Author and/or Licensor
designate another party or parties (e.g. a sponsor institute, publishing
entity, journal) for attribution ("Attribution Parties") in
Licensor's copyright notice, terms of service or by other reasonable means, the
name of such party or parties; the title of the Work if supplied; to the extent
reasonably practicable, the Uniform Resource Identifier, if any, that Licensor
specifies to be associated with the Work, unless such URI does not refer to the
copyright notice or licensing information for the Work; and, consistent with
Section 3(b) in the case of a Derivative Work, a credit identifying the use of
the Work in the Derivative Work (e.g., "French translation of the Work by
Original Author," or "Screenplay based on original Work by Original
Author"). The credit required by this Section 4(c) may be implemented in
any reasonable manner; provided, however, that in the case of a Derivative Work
or Collective Work, at a minimum such credit will appear, if a credit for all
contributing authors of the Derivative Work or Collective Work appears, then as
part of these credits and in a manner at least as prominent as the credits for
the other contributing authors. For the avoidance of doubt, You may only use
the credit required by this Section for the purpose of attribution in the
manner set out above and, by exercising Your rights under this License, You may
not implicitly or explicitly assert or imply any connection with, sponsorship
or endorsement by the Original Author, Licensor and/or Attribution Parties, as
appropriate, of You or Your use of the Work, without the separate, express
prior written permission of the Original Author, Licensor and/or Attribution
Parties.
5.
Representations, Warranties and Disclaimer
UNLESS
OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE
WORK AS-IS AND ONLY TO THE EXTENT OF ANY RIGHTS HELD IN THE LICENSED WORK BY
THE LICENSOR. THE LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING,
WITHOUT LIMITATION, WARRANTIES OF TITLE, MARKETABILITY, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR
OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT
DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6.
Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO
EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS
LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
7.
Termination
This
License and the rights granted hereunder will terminate automatically upon any
breach by You of the terms of this License. Individuals or entities who have
received Derivative Works or Collective Works from You under this License,
however, will not have their licenses terminated provided such individuals or
entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7,
and 8 will survive any termination of this License.
Subject
to the above terms and conditions, the license granted here is perpetual (for
the duration of the applicable copyright in the Work). Notwithstanding the
above, Licensor reserves the right to release the Work under different license
terms or to stop distributing the Work at any time; provided, however that any
such election will not serve to withdraw this License (or any other license
that has been, or is required to be, granted under the terms of this License),
and this License will continue in full force and effect unless terminated as
stated above.
8.
Miscellaneous
Each time
You distribute or publicly digitally perform the Work (as defined in Section 1
above) or a Collective Work (as defined in Section 1 above), the Licensor
offers to the recipient a license to the Work on the same terms and conditions
as the license granted to You under this License.
Each time
You distribute or publicly digitally perform a Derivative Work, Licensor offers
to the recipient a license to the original Work on the same terms and
conditions as the license granted to You under this License.
If any
provision of this License is invalid or unenforceable under applicable law, it
shall not affect the validity or enforceability of the remainder of the terms
of this License, and without further action by the parties to this agreement,
such provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.
No term
or provision of this License shall be deemed waived and no breach consented to
unless such waiver or consent shall be in writing and signed by the party to be
charged with such waiver or consent.
This
License constitutes the entire agreement between the parties with respect to
the Work licensed here. There are no understandings, agreements or
representations with respect to the Work not specified here. Licensor shall not
be bound by any additional provisions that may appear in any communication from
You. This License may not be modified without the mutual written agreement of
the Licensor and You.
Creative
Commons Notice
Creative
Commons is not a party to this License, and makes no warranty whatsoever in
connection with the Work. Creative Commons will not be liable to You or any
party on any legal theory for any damages whatsoever, including without
limitation any general, special, incidental or consequential damages arising in
connection to this license. Notwithstanding the foregoing two (2) sentences, if
Creative Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
Except
for the limited purpose of indicating to the public that the Work is licensed
under the CCPL, Creative Commons does not authorize the use by either party of
the trademark "Creative Commons" or any related trademark or logo of
Creative Commons without the prior written consent of Creative Commons. Any
permitted use will be in compliance with Creative Commons' then-current
trademark usage guidelines, as may be published on its website or otherwise
made available upon request from time to time. For the avoidance of doubt, this
trademark restriction does not form part of this License.
Creative
Commons may be contacted at http://creativecommons.org/.