Using Ogre with the Newton Game Dynamics physics SDK

Introduction

This tutorial is intended to explain how to setup a simple project using OgreNewt.

It was created with Ogre 1.0.0 and Newton Game Dynamics 1.31.

If there are problems with the current versions, please tell it in the OgreNewt section of the Ogre Addons forum.

If you want to use Newton 2.0 (beta), then also look to OgreNewt 2.

Requirements:

  1. For this tutorial I will assume you have Ogre 1.1.x (Dagon) installed on your machine, and compiling and running properly. There are plenty of other tutorials for that! Note that if you have version 1.0.x of Ogre, this tutorial will work as well, with one small change (noted below).
  2. I will also assume you have installed the Newton Game Dynamics (from here on referred to as "Newton") on your system as well. If you haven't, however, just go to http://www.newtondynamics.com and download the SDK. It's free.
  3. Finally, I will also be using my "OgreNewt" library to connect Ogre and Newton. OgreNewt is available as a part of "ogreaddons" in the Ogre CVS, but is also available from my website walaber.com. As we go through the tutorial I will also explain the basics of Newton, and how OgreNewt implements itself.
  4. Now might be a good idea to download the Media pack for this tutorial.

Getting Started

The first thing we need to do, is get OgreNewt compiled, and up and running. I will be assuming you have a directory tree setup like below:

Directory structure:
<some_dir>/OGRE/ogrenew <- ogre install dir <some_dir>/OGRE/ogreaddons/OgreNewt/ <- OgreNewt install dir. <some_dir>/NewtonSDK <- Newton SDK install dir <some_dir>/tinyxml <- Tinyxml library (used only for demo08, not in OgreNewt itself)

If your directory tree is different, you will need to modify the OgreNewt project files to get it to compile properly.

Okay, so open up VC++, and load the "OgreNewt" solution. You should see 9 total projects:

  1. OgreNewt_Main - this is the library itself, where all classes are defined.
  2. Demo01_TheBasics - an extremely simple demo, where you can throw objects at a solid object, and watch them interact.
  3. Demo02_Joints - another simple demo, showing TreeCollision bodies, and simple Joints.
  4. Demo03_CollisionCallbacks - how to use advanced collision callbacks to control object behavior through the example of a conveyor belt.
  5. Demo04_Raycasting - using raycasting with rigid bodies
  6. Demo05_SimpleVehicle - how to use the Newton vehicle system
  7. Demo06_SimpleBuoyancy - how to use the Newton buoyancy system
  8. Demo07_CustomJoints - simple example of how to make your own joints with OgreNewt.
  9. Demo08_RagdollExample - an example of how to make skinned ragdolls using OgreNewt.


Assuming your directory structure is set up like I have shown above, you should be able to compile the solution right away with no problems. Do so now. Note that you will have to have tinyxml compiled properly (use the STL version) to get demo08 to compile properly.

Now you can navigate to the "OgreNewt/Bin/Debug" or "OgreNewt/Bin/Release" directories, and there should be the executables for the demos there. Copy over the standard Ogre .dll files, as well as the newton.dll file from your Newton SDK directory, and try running the demos.

Demo Controls:

  1. MOUSE to look around
  2. ARROW KEYS to move / strafe
  3. SPACE BAR to throw objects
  4. ESC to quit.


Okay, if you've made it this far, you're ready to try and make your own simple OgreNewt application. I'll be using
the standard ExampleApplication and ExampleFrameListener classes used in most Ogre tutorials. if you've never made
an Ogre application with these classes, you might want to read through a few general Ogre tutorials to get up to speed
first.

Okay... so first let's set up our Application class. Create a new project and add a new header file called "OgreNewtApplication.h". Open it up and set up the basic class outline like below:

OgreNewtApplication.h

#ifndef _OGRENEWTAPPLICATION_
 #define _OGRENEWTAPPLICATION_
 
 #include "ExampleApplication.h"
 
 class OgreNewtApplication :
     public ExampleApplication
 {
 public:
     OgreNewtApplication(void);
     ~OgreNewtApplication(void);
 
     void createScene();
 
     void createFrameListener(void);
 };


This should look familiar... it's just a standard inherited ExampleApplication class. First we need to set up the various include directories for our project. in the C/C++ section of the project settings, make sure the following directories are in the "include directories" list:

include directories
ogrenew/ogremain/include
ogrenew/samples/common/include
ogreaddons/OgreNewt/OgreNewt_Main/inc
ogreaddons/OgreNewt/demos/Include
NewtonSDK/sdk

library directories
ogrenew/ogremain/lib/debug <or release> ogreaddons/OgreNewt_Main/lib/debug <or release> NewtonSDK/dll/

Now we need to add the various pieces necessary to make a Newton application. first, let's include the OgreNewt main header:

#include <OgreNewt.h>

Okay, simple enough. Now add the following line to the private section of the class:

OgreNewt::World* mWorld;

If you have auto-complete set up in your -IDE, you should see a bunch of classes and namespaces pop up when you type "OgreNewt::". Let's now take a minute and talk about the Newton SDK, and how it works.

Newton SDK in a Nutshell

This section is a quick introduction to the Newton SDK, and how it works. it is by no means a substitute to the SDK documentation, which is included with the SDK. My OgreNewt library is pretty much a 1:1 conversion of the Newton functions into a class-based environment, so most of the function descriptions in the Newton documentation apply directly to OgreNewt.

Anyway, Newton has a few basic elements used to describe the physics world... they are:

WORLD (OgreNewt
:World)~/np~: This is the "space" in which all objects exist. all other objects require a World to be created, and are contained within that world. in most applications, you will only need 1 World object, inside which you will place all other objects. however the system allows for multiple worlds to co-exist if desired. this tutorial will only use 1 world.
RIGID BODY (OgreNewt
:Body): This is the basic object in the physics world. it represents a solid (rigid) body, which can interact with other bodies in the scene. Bodies can have mass, size, and shape. Basically everything you want to be affected by physics calculations needs a Body.
COLLISION (OgreNewt
:Collision): This is an object that represents a certain shape. Rigid Bodies (above) require a Collision object to define their shape. You can re-use Collision objects. so for example if you want 100 different crates in your scene (that are all the same size), you would create 1 Collision object, and use it when creating all 100 seperate Body objects. Newton supports several different ways to describe collision. they are:
  • PRIMITIVE SHAPES : these include: Boxes, Ellipsoids, Cylinders, Capsules, Cones, and Chamfer Cylinders (closed donuts).
  • CONVEX HULLS : Convex hulls are a more general primitive type. they take a series of points in space, and create the smallest possible convex shape based on all of those points. in most cases, you would use the vertices that makeup a model for the points. this results in a primitive shape that looks something like your 3D model wrapped up in wrapping paper.
  • TREE COLLISIONS : the name may not be too obvious, but "TreeCollision" objects are just general polygon collision. for example if you have a large city made of polygons, you can create a collision object from it. note that TreeCollision objects are special in that they CANNOT be used for active rigid bodies (aka movable bodies). all Bodies created from a TreeCollision will automatically have infinite mass, and therefore be completely immobile. they are best used for "background" objects that never need to move. for dynamic, moving objects, you must use convex hulls or the general primitives.
  • Note that you can combine any of the above collisions to create "CompoundCollision" objects to define more complex shapes.
  • On this page of Newton Wiki are pictures of collision primitives.
JOINT (OgreNewt
:Joint): Joints are connections between 2 Bodies that affect the way they interact. for example you can connect 2 bodies together with a hinge joint to create a door.

{DL()}
MATERIAL ({MONO()}OgreNewt::MaterialID && OgreNewt::MaterialPair{MONO}): Materials are how Newton lets you adjust the interaction between bodies when they collide. This can be as simple as adjusting the friction, or much more complex. The material system is pretty simple. First you create "MaterialID" objects to represent each material you might need in your system. Examples of common materials might be: wood_mat, metal_mat, plastic_mat, or player_mat, etc.
{DL}

Then you build what is called a "MaterialPair". A material pair is a description of what happens when 2 materials collide with each other. For example, you might create a material pair for collisions between iron and steel. Then you will know any time an "iron" and "steel" object come in contact. You can then create sparks, or sound effects, etc.

Okay, those are the big, basic objects that are used in Newton. Note that there are also special objects for creating ragdolls and vehicles as well. See the Newton documentation for more information on them. At this time, OgreNewt has no special implementation for these objects.

The Newton World

Okay, so back to our OgreNewtApplication class. as you can see, we've now added a pointer to an OgreNewt::World, which
will be the main World in which we place our rigid bodies. now create a new OgreNewtApplication.cpp source file, and add the basic elements necessary. you should end up with something looking like this:

OgreNewtApplication.cpp

#include ".\ogrenewtapplication.h"
 
 OgreNewtApplication::OgreNewtApplication(void)
 {
 }
 
 OgreNewtApplication::~OgreNewtApplication(void)
 {
 }
 
 void OgreNewtApplication::createScene()
 {
 
 }
 
 void OgreNewtApplication::createFrameListener()
 {
 
 }


Now, let's create the Newton world in the constructor for the application class. Add this line:

mWorld = new OgreNewt::World();

This line creates the OgreNewt::World object. You need to create this object before creating any other Newton objects,
as they will all require you pass a pointer to a World object. You might also want to add a line to delete the world in the
destructor:

delete mWorld;

Now there's one more thing we want to add to the Application class while we're here: A frame listener. In most demos,
they have you create a FrameListener class inherited from ExampleFrameListener. We'll do the same in this demo, but
also add a special FrameListener just for updating and debugging the Newton world. First, setup the standard ExampleFrameListener class, in your createFrameListener() function like this:

OgreNewtApplication.cpp

void OgreNewtApplication::createFrameListener()
 {
     mFrameListener = new ExampleFrameListener( mWindow, mCamera );
     mRoot->addFrameListener( mFrameListener );
 }


Now we'll add a frame listener to update the physics, and provide physics debugging features. Luckily, I've included
such a frame listener in the OgreNewt library, called "BasicFrameListener". Add a member pointer variable in the
Application class like this:

OgreNewt::BasicFrameListener* mOgreNewtListener;

And then, add these lines to the createFrameListener() function:

mOgreNewtListener = new OgreNewt::BasicFrameListener( mWindow, mCamera, mSceneMgr, mWorld, 120 );
 mRoot->addFrameListener( mOgreNewtListener );

The OgreNewt::BasicFrameListener is a simple frame listener that updates the Newton world each frame, with a simple
time-slicing method, which means you can control the rate at which the physics update. The last paramater you
pass to the constructor is the desired update fps for the physics system. By adding this FrameListener to your application,
the physics will automatically update. Also, the frame listener has a simple debug system implemented, which I'll
discuss later. note that for more complex applications, it would probably be better to implement your own frame listener
for the physics, which gives more control.

Okay, so everything is all set up. now let's build a simple Newton scene. For this demo, we're going to make a very simple scene, which creates a basic floow (out of a box), and drops several primitive objects onto the ground.

So let's get started. first let's make a simple ground. First we'll make a standard visual object, like any other in Ogre,
and then add the physics Rigid Body "behind it". Now would be a good time to download the MESH PACK for this tutorial, and unzip the .mesh files somewhere your Ogre program will find them. okay, first add the mesh as usual:

Ogre::Vector3 size(10.0,1.0,10.0);
 Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 Ogre::Entity* ent = mSceneMgr->createEntity( "floorobj", "box.mesh" );
 node->attachObject( ent );
 node->setScale( size );


Okay, now let's make the Rigid Body that represents this object. It's actually pretty simple:
first we make a collision object that represents the shape:

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Box( mWorld, size );

Then, we make a Rigid Body object from this collision object.

OgreNewt::Body* floorbody = new OgreNewt::Body( mWorld, col );

Notice that we also must pass a pointer to our Newton World object as well when making these objects. now our body is created, finally we need to "connect" the Rigid Body, to the visual 3D object attached to the SceneNode. what does this
mean? well, Newton has a really interesting system of callbacks, which means that if you setup your scene properly,
Newton will automatically update the position and rotation of objects for you! for example, let's say you have 50 different
objects in a scene. when you ask Newton to update the physics, it calculates the new position and rotation of all of the
objects in the scene, based on physical laws. with many physics engines, you then need to perform some kind of loop,
which goes through all of the physics bodies in the scene, gets their orientation, and applies this to their "visual" object,
to match them up. However Newton has a callback system built in, which does this for you. this is ultimately very cool
because it's automated, and also more efficient, because Newton only calls the callback for bodies that are moving, bodies
that have not moved since the last update are properly ignored. Anyway, the way this is implemented in OgreNewt is through
the "attachToNode()" member function of the OgreNewt::Body class. basically this function says "this SceneNode has some
meshes attached to it, which are a visual representation of this Rigid Body. when this Rigid Body moves, please also
move this SceneNode". it's as simple as that. here's how it's done:

floorbody->attachToNode( node );

Finally, we want to set the initial position of our floor. let's place it in the center of the world, down 5 units on the
Y axis, like so:

floorbody->setPositionOrientation( Ogre::Vector3(0,-5,0), Ogre::Quaternion::IDENTITY );
 delete col;

This member function manually sets the position and orientation of a RigidBody, as well as the SceneNode attached to it (if any). You'll notice we also delete the Collision object, as we don't need it anymore.

Now our floor is complete. next, let's make a few other primitive shapes to fall onto the floor! First let's make a simple
cylinder-shaped body. The first few steps are exactly like above:

// CYLINDER BODY
 // cylinder with a radius of 0.5, height of 1.3
 size = Ogre::Vector3( 1.3, 0.5, 0.5 );
 node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 ent = mSceneMgr->createEntity("cylinder_body", "cylinder.mesh" );
 node->attachObject( ent );
 node->setScale( size );
 
 // rigid body.
 col = new OgreNewt::CollisionPrimitives::Cylinder( mWorld, 0.5, 1.3 );
 OgreNewt::Body* bod = new OgreNewt::Body( mWorld, col );
 bod->attachToNode( node );
 
 // initial position
 bod->setPositionOrientation( Ogre::Vector3(-2,3,2), Ogre::Quaternion::IDENTITY );
 delete col;


Okay, all of that should look familiar, it's very similar to the Floor code. however, we want this body to be "dynamic",
in the sense that it should be affected by gravity, and fall down, hitting other objects, and generally impressing us.
To do so, we need to define a few other properties of the Rigid Body, namely Mass and Moment of Inertia. Mass is simple,
you can use any units you see fit, although personally I recommend using Kilograms as a standard. Inertia might not be so
intuitive, as it's a value that represents an objects resistance to rotation around a specific axis. many factors can
affect this value, and getting truly accurate values is beyond me. however, there are some handy formulas available on
the internet for calculating the moment of inertia for certain primitive shapes. what's even more handy, is that I've
included these functions right inside OgreNewt. there just happens to be a function for cylinders, so we'll use it to
calculate the inertia values for us, based on the mass and size of the object. here's how we set it up:

Ogre::Real mass = 10.0;
 Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid( mass, 0.5, 1.3 );
 
 bod->setMassMatrix( mass, inertia );

Now the object has mass! however if you were to compile and run your program right now (go ahead and try if you want!), the body would not fall to the ground. This is because we haven't applied any forces to the object, to set it
in motion. In Physics simulations, the most common force is gravity. So how do we add gravity with Newton?

Well, in a similar fashion to the callback that positions and orients visual objects for you, Newton also provides
a callback for applying forces to a body. this way, you can create different general callbacks, which apply some
kind of force to a body, and by simply setting the callback for the body, you can adjust the forces that act upon it.
I have yet to fully implement the details of adding custom callbacks into OgreNewt, but it's not too difficult to
implement if you read the documentation for Newton, and have a look at the OgreNewt source code. however I have included
a "basicForceTorqueCallback" right into the OgreNewt::Body class, which applies a constant gravitational (-Y) force of 9.8units/sec^2 to the body. to set this callback, simply do the following:

bod->setStandardForceCallback();

And voila! Your Rigid Body now has gravity. That's the basic setup for making a rigid body in this tutorial. Let's
now add a few more bodies to the scene, following the same steps we have seen above:

// CONE BODY
// cone with a radius of 0.8, height of 1.0
size = Ogre::Vector3( 1.0, 0.8, 0.8 );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
ent = mSceneMgr->createEntity("cone_body", "cone.mesh" );
node->attachObject( ent );
node->setScale( size ); 
  
// rigid body.
col = new OgreNewt::CollisionPrimitives::Cone( mWorld, 0.8, 1.0 );
bod = new OgreNewt::Body( mWorld, col );
bod->attachToNode( node );  
 
// initial position
bod->setPositionOrientation( Ogre::Vector3(2,3,2), Ogre::Quaternion::IDENTITY );
delete col;
 
mass = 10.0;
inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid( mass, 0.5, 1.3 );
bod->setMassMatrix( mass, inertia );
bod->setStandardForceCallback();
 
// BOX BODY
// standard 1x1x1 cube.
size = Ogre::Vector3( 1, 1, 1 );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
ent = mSceneMgr->createEntity("box_body", "box.mesh" );
node->attachObject( ent );
node->setScale( size );
 
// rigid body.
col = new OgreNewt::CollisionPrimitives::Box( mWorld, size );
bod = new OgreNewt::Body( mWorld, col );
bod->attachToNode( node );
 
// initial position
bod->setPositionOrientation( Ogre::Vector3(0,3,-2),Ogre::Quaternion::IDENTITY );
delete col;
 
mass = 10.0;
inertia = OgreNewt::MomentOfInertia::CalcBoxSolid( mass, size );
bod->setMassMatrix( mass, inertia );
bod->setStandardForceCallback();

Okay, that's it! Don't forget to also add a light to your scene, and possibly set a good starting point for the camera. Now compile and run your project, you should have 3 objects that fall and bounce on the ground we made.

This should be enough to get you started with Ogre and Newton, using my OgreNewt library... although I think the main
ideas in the tutorial would work for your own implementation of Newton in Ogre as well. Good luck, and good physics!

  • Finally, you can download a copy of this entire project, including all media, and the MSVC++ (7.1) project files here.

Note

If you get an error like this:
Unhandled exception at 0x00423d76 in newtontest.exe: 0xC0000005: Access violation reading location 0xfeef003e
In the line: m_debugnode->detachAllObjects();

You need to deinit the debugger. To do this, add
OgreNewt::Debugger::getSingleton().deInit();
to the destructor of your application class.

See also


Alias: Newton Game Dynamics
Alias: Newton_Game_Dynamics

<HR>
Creative Commons Copyright -- Some rights reserved.


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. 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 a number of 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.
  • "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.
  • "Licensor" means the individual or entity that offers the Work under the terms of this License.
  • "Original Author" means the individual or entity 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.
  • "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.

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;
  • 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 via a performance rights society (e.g. ASCAP, BMI, SESAC), 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 society 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 alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above 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 clause 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 clause 4(c), as requested.
  • You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above 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 this License.
  • If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must 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 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 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"). Such credit 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 where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, 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 or a Collective Work, 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.