void PhysicsRigidBody::applyImpulse(const Vector3& impulse, const Vector3* relativePosition) { // If the impulse is significant enough, activate the rigid body // to make sure that it isn't sleeping and apply the impulse. if (impulse.lengthSquared() > MATH_EPSILON) { GP_ASSERT(_body); _body->activate(); if (relativePosition) { _body->applyImpulse(BV(impulse), BV(*relativePosition)); } else _body->applyCentralImpulse(BV(impulse)); } }
VertexFormat::VertexFormat(const Element* elements, unsigned int elementCount) : _vertexSize(0) { GP_ASSERT(elements); // Copy elements and compute vertex size for (unsigned int i = 0; i < elementCount; ++i) { // Copy element Element element; memcpy(&element, &elements[i], sizeof(Element)); _elements.push_back(element); _vertexSize += element.size * sizeof(float); } }
void Vec2::clamp(const Vec2& min, const Vec2& max) { GP_ASSERT(!(min.x > max.x || min.y > max.y )); // Clamp the x value. if (x < min.x) x = min.x; if (x > max.x) x = max.x; // Clamp the y value. if (y < min.y) y = min.y; if (y > max.y) y = max.y; }
const ScriptTarget::Event* ScriptTarget::getScriptEvent(const char* eventName) const { GP_ASSERT(eventName); // Lookup the event for this name const Event* event = NULL; RegistryEntry* re = _scriptRegistries; while (re) { if ((event = re->registry->getEvent(eventName)) != NULL) break; re = re->next; } return event; }
void Transform::removeListener(Transform::Listener* listener) { GP_ASSERT(listener); if (_listeners) { for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr) { if ((*itr).listener == listener) { _listeners->erase(itr); break; } } } }
PhysicsCollisionObject::~PhysicsCollisionObject() { SAFE_DELETE(_motionState); if (_scriptListeners) { for (unsigned int i = 0; i < _scriptListeners->size(); i++) { SAFE_DELETE((*_scriptListeners)[i]); } SAFE_DELETE(_scriptListeners); } GP_ASSERT(Game::getInstance()->getPhysicsController()); Game::getInstance()->getPhysicsController()->destroyShape(_collisionShape); }
void Plane::intersection(const Plane& p1, const Plane& p2, const Plane& p3, kmVec3* point) { GP_ASSERT(point); // The planes' normals must be all normalized (which we guarantee in the Plane class). // Calculate the determinant of the kmMat4 (i.e | n1 n2 n3 |). float det = p1._normal.x * (p2._normal.y * p3._normal.z - p2._normal.z * p3._normal.y) - p2._normal.x *(p1._normal.y * p3._normal.z - p1._normal.z * p3._normal.y) + p3._normal.x * (p1._normal.y * p2._normal.z - p1._normal.z * p2._normal.y); // If the determinant is zero, then the planes do not all intersect. if (fabs(det) <= MATH_EPSILON) return; // Create 3 points, one on each plane. // (We just pick the point on the plane directly along its normal from the origin). float p1x = -p1._normal.x * p1._distance; float p1y = -p1._normal.y * p1._distance; float p1z = -p1._normal.z * p1._distance; float p2x = -p2._normal.x * p2._distance; float p2y = -p2._normal.y * p2._distance; float p2z = -p2._normal.z * p2._distance; float p3x = -p3._normal.x * p3._distance; float p3y = -p3._normal.y * p3._distance; float p3z = -p3._normal.z * p3._distance; // Calculate the cross products of the normals. float c1x = (p2._normal.y * p3._normal.z) - (p2._normal.z * p3._normal.y); float c1y = (p2._normal.z * p3._normal.x) - (p2._normal.x * p3._normal.z); float c1z = (p2._normal.x * p3._normal.y) - (p2._normal.y * p3._normal.x); float c2x = (p3._normal.y * p1._normal.z) - (p3._normal.z * p1._normal.y); float c2y = (p3._normal.z * p1._normal.x) - (p3._normal.x * p1._normal.z); float c2z = (p3._normal.x * p1._normal.y) - (p3._normal.y * p1._normal.x); float c3x = (p1._normal.y * p2._normal.z) - (p1._normal.z * p2._normal.y); float c3y = (p1._normal.z * p2._normal.x) - (p1._normal.x * p2._normal.z); float c3z = (p1._normal.x * p2._normal.y) - (p1._normal.y * p2._normal.x); // Calculate the point of intersection using the formula: // x = (| n1 n2 n3 |)^-1 * [(x1 * n1)(n2 x n3) + (x2 * n2)(n3 x n1) + (x3 * n3)(n1 x n2)] float s1 = p1x * p1._normal.x + p1y * p1._normal.y + p1z * p1._normal.z; float s2 = p2x * p2._normal.x + p2y * p2._normal.y + p2z * p2._normal.z; float s3 = p3x * p3._normal.x + p3y * p3._normal.y + p3z * p3._normal.z; float detI = 1.0f / det; point->x = (s1 * c1x + s2 * c2x + s3 * c3x) * detI; point->y = (s1 * c1y + s2 * c2y + s3 * c3y) * detI; point->z = (s1 * c1z + s2 * c2z + s3 * c3z) * detI; }
void* trackRef(Ref* ref) { GP_ASSERT(ref); // Create memory allocation record. RefAllocationRecord* rec = (RefAllocationRecord*)malloc(sizeof(RefAllocationRecord)); rec->ref = ref; rec->next = __refAllocations; rec->prev = 0; if (__refAllocations) __refAllocations->prev = rec; __refAllocations = rec; ++__refAllocationCount; return rec; }
PostProcessSample::Compositor* PostProcessSample::Compositor::create(FrameBuffer* srcBuffer, FrameBuffer* dstBuffer, const char* materialPath, const char* techniqueId) { GP_ASSERT(srcBuffer); Material* material = Material::create(materialPath); Texture::Sampler* sampler = Texture::Sampler::create(srcBuffer->getRenderTarget()->getTexture()); material->getParameter("u_texture")->setValue(sampler); SAFE_RELEASE(sampler); if (_quadModel == NULL) { Mesh* mesh = Mesh::createQuadFullscreen(); _quadModel = Model::create(mesh); SAFE_RELEASE(mesh); } return new Compositor(srcBuffer, dstBuffer, material, techniqueId); }
AnimationClip* Animation::findClip(const char* id) const { if (_clips) { size_t clipCount = _clips->size(); for (size_t i = 0; i < clipCount; i++) { AnimationClip* clip = _clips->at(i); GP_ASSERT(clip); if (clip->_id.compare(id) == 0) { return clip; } } } return NULL; }
bool ScriptTarget::removeScript(const char* path) { GP_ASSERT(path); ScriptEntry* se = _scripts; while (se) { if (strcmp(se->script->getPath(), path) == 0 && se->script->getScope() == Script::PROTECTED) { removeScript(se); return true; } se = se->next; } return false; }
void AnimationClip::onEnd() { _blendWeight = 1.0f; resetClipStateBit(CLIP_ALL_BITS); // Notify end listeners if any. if (_endListeners) { std::vector<Listener*>::iterator listener = _endListeners->begin(); while (listener != _endListeners->end()) { GP_ASSERT(*listener); (*listener)->animationEvent(this, Listener::END); listener++; } } }
AudioSource* AudioSource::create(Properties* properties) { // Check if the properties is valid and has a valid namespace. GP_ASSERT(properties); if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0)) { GP_ERROR("Failed to load audio source from properties object: must be non-null object and have namespace equal to 'audio'."); return NULL; } std::string path; if (!properties->getPath("path", &path)) { GP_ERROR("Audio file failed to load; the file path was not specified."); return NULL; } // Create the audio source. AudioSource* audio = AudioSource::create(path.c_str()); if (audio == NULL) { GP_ERROR("Audio file '%s' failed to load properly.", path.c_str()); return NULL; } // Set any properties that the user specified in the .audio file. if (properties->exists("looped")) { audio->setLooped(properties->getBool("looped")); } if (properties->exists("gain")) { audio->setGain(properties->getFloat("gain")); } if (properties->exists("pitch")) { audio->setPitch(properties->getFloat("pitch")); } Vector3 v; if (properties->getVector3("velocity", &v)) { audio->setVelocity(v); } return audio; }
void Animation::setTransformRotationOffset(Curve* curve, unsigned int propertyId) { GP_ASSERT(curve); switch (propertyId) { case Transform::ANIMATE_ROTATE: case Transform::ANIMATE_ROTATE_TRANSLATE: curve->setQuaternionOffset(ANIMATION_ROTATE_OFFSET); return; case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE: curve->setQuaternionOffset(ANIMATION_SRT_OFFSET); return; } return; }
void BoundingSphere::merge(const BoundingSphere& sphere) { if (sphere.isEmpty()) return; // Calculate the distance between the two centers. float vx = center.x - sphere.center.x; float vy = center.y - sphere.center.y; float vz = center.z - sphere.center.z; float d = sqrt(vx * vx + vy * vy + vz * vz); // If one sphere is contained inside the other, set to the larger sphere. if (d <= (sphere.radius - radius)) { center = sphere.center; radius = sphere.radius; return; } else if (d <= (radius - sphere.radius)) { return; } // Calculate the unit vector between the two centers. GP_ASSERT(d != 0.0f); float dI = 1.0f / d; vx *= dI; vy *= dI; vz *= dI; // Calculate the new radius. float r = (radius + sphere.radius + d) * 0.5f; // Calculate the new center. float scaleFactor = (r - sphere.radius); vx = vx * scaleFactor + sphere.center.x; vy = vy * scaleFactor + sphere.center.y; vz = vz * scaleFactor + sphere.center.z; // Set the new center and radius. center.x = vx; center.y = vy; center.z = vz; radius = r; }
void Joystick::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip) { GP_ASSERT(spriteBatch); // If the joystick is not absolute, then only draw if it is active. if (!_relative || (_relative && _state == ACTIVE)) { if (!_relative) { _screenRegion.x = _viewportClipBounds.x + (_viewportClipBounds.width - _screenRegion.width) / 2.0f; _screenRegion.y = _viewportClipBounds.y + (_viewportClipBounds.height - _screenRegion.height) / 2.0f; } // Draw the outer image. Theme::ThemeImage* outer = getImage("outer", _state); if (outer) { const Theme::UVs& uvs = outer->getUVs(); const Vector4& color = outer->getColor(); if (_relative) spriteBatch->draw(_screenRegion.x, _screenRegion.y, _outerSize->x, _outerSize->y, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color); else spriteBatch->draw(_screenRegion.x, _screenRegion.y, _outerSize->x, _outerSize->y, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color, _viewportClipBounds); } // Draw the inner image. Theme::ThemeImage* inner = getImage("inner", _state); if (inner) { Vector2 position(_screenRegion.x, _screenRegion.y); // Adjust position to reflect displacement. position.x += _displacement.x; position.y += -_displacement.y; // Get the uvs and color and draw. const Theme::UVs& uvs = inner->getUVs(); const Vector4& color = inner->getColor(); if (_relative) spriteBatch->draw(position.x, position.y, _innerSize->x, _innerSize->y, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color); else spriteBatch->draw(position.x, position.y, _innerSize->x, _innerSize->y, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color, _viewportClipBounds); } } }
Vector3 PhysicsConstraint::getWorldCenterOfMass(const Node* node) { GP_ASSERT(node); const BoundingSphere& sphere = node->getBoundingSphere(); if (!(sphere.center.isZero() && sphere.radius == 0)) { // The world-space center of mass is the sphere's center. return sphere.center; } // Warn the user that the node has no bounding volume. GP_WARN("Node %s' has no bounding volume - center of mass is defaulting to local coordinate origin.", node->getId()); Vector3 center; node->getWorldMatrix().transformPoint(¢er); return center; }
int Text::getPropertyId(TargetType type, const char* propertyIdStr) { GP_ASSERT(propertyIdStr); if (type == AnimationTarget::TRANSFORM) { if (strcmp(propertyIdStr, "ANIMATE_OPACITY") == 0) { return Text::ANIMATE_OPACITY; } else if (strcmp(propertyIdStr, "ANIMATE_COLOR") == 0) { return Text::ANIMATE_COLOR; } } return AnimationTarget::getPropertyId(type, propertyIdStr); }
void TileSet::cloneInto(TileSet* tileset, NodeCloneContext &context) const { GP_ASSERT(tileset); // Clone properties tileset->_tiles = new Vector2[tileset->_rowCount * tileset->_columnCount]; memset(tileset->_tiles, -1, sizeof(float) * tileset->_rowCount * tileset->_columnCount * 2); memcpy(tileset->_tiles, _tiles, sizeof(Vector2) * tileset->_rowCount * tileset->_columnCount); tileset->_tileWidth = _tileWidth; tileset->_tileHeight = _tileHeight; tileset->_rowCount = _rowCount; tileset->_columnCount = _columnCount; tileset->_width = _tileWidth * _columnCount; tileset->_height = _tileHeight * _rowCount; tileset->_opacity = _opacity; tileset->_color = _color; tileset->_batch = _batch; }
Material* Material::create(Effect* effect) { GP_ASSERT(effect); // Create a new material with a single technique and pass for the given effect. Material* material = new Material(); Technique* technique = new Technique(NULL, material); material->_techniques.push_back(technique); Pass* pass = new Pass(NULL, technique, effect); technique->_passes.push_back(pass); effect->addRef(); material->_currentTechnique = technique; return material; }
Container* Container::create(Theme::Style* style, Properties* properties, Theme* theme) { GP_ASSERT(properties); const char* layoutString = properties->getString("layout"); Container* container = Container::create(getLayoutType(layoutString)); container->initialize(style, properties); container->_scroll = getScroll(properties->getString("scroll")); container->_scrollBarsAutoHide = properties->getBool("scrollBarsAutoHide"); if (container->_scrollBarsAutoHide) { container->_scrollBarOpacity = 0.0f; } container->addControls(theme, properties); container->_layout->update(container, container->_scrollPosition); return container; }
void AnimationClip::setRepeatCount(float repeatCount) { GP_ASSERT(repeatCount == REPEAT_INDEFINITE || repeatCount > 0.0f); _repeatCount = repeatCount; if (repeatCount == REPEAT_INDEFINITE) { _activeDuration = _duration + _loopBlendTime; } else { _activeDuration = _duration * _repeatCount; if (repeatCount > 1.0f && _loopBlendTime > 0.0f) _activeDuration += std::ceil(repeatCount - 1.0f) * _loopBlendTime; } }
Material* Material::clone(NodeCloneContext &context) const { Material* material = new Material(); RenderState::cloneInto(material, context); for (std::vector<Technique*>::const_iterator it = _techniques.begin(); it != _techniques.end(); ++it) { const Technique* technique = *it; GP_ASSERT(technique); Technique* techniqueClone = technique->clone(material, context); material->_techniques.push_back(techniqueClone); if (_currentTechnique == technique) { material->_currentTechnique = techniqueClone; } } return material; }
void MeshSkin::setJoint(Joint* joint, unsigned int index) { GP_ASSERT(index < _joints.size()); if (_joints[index]) { _joints[index]->removeSkin(this); SAFE_RELEASE(_joints[index]); } _joints[index] = joint; if (joint) { joint->addRef(); joint->addSkin(this); } }
void Container::keyEvent(Keyboard::KeyEvent evt, int key) { std::vector<Control*>::const_iterator it; for (it = _controls.begin(); it < _controls.end(); it++) { Control* control = *it; GP_ASSERT(control); if (!control->isEnabled()) { continue; } if (control->isContainer() || control->getState() == Control::FOCUS) { control->keyEvent(evt, key); } } }
void MeshSkin::setJoint(Joint* joint, unsigned int index) { GP_ASSERT(index < _joints.size()); if (_joints[index]) { _joints[index]->_skinCount--; SAFE_RELEASE(_joints[index]); } _joints[index] = joint; if (joint) { joint->addRef(); joint->_skinCount++; } }
void ScriptController::loadScript(const char* path, bool forceReload) { GP_ASSERT(path); std::set<std::string>::iterator iter = _loadedScripts.find(path); if (iter == _loadedScripts.end() || forceReload) { bool success = false; if (iter == _loadedScripts.end()) _loadedScripts.insert(path); // insert before loading script to prevent load recursion #ifdef __ANDROID__ const char* scriptContents = FileSystem::readAll(path); if (luaL_dostring(_lua, scriptContents)) { GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1)); } else { success = true; } SAFE_DELETE_ARRAY(scriptContents); #else std::string fullPath; if (!FileSystem::isAbsolutePath(path)) { fullPath.append(FileSystem::getResourcePath()); } fullPath.append(path); if (luaL_dofile(_lua, fullPath.c_str())) { GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1)); } else { success = true; } #endif if (!success && (iter == _loadedScripts.end())) { iter = _loadedScripts.find(path); _loadedScripts.erase(iter); } } }
static RenderState::CullFaceSide parseCullFaceSide(const char* value) { GP_ASSERT(value); // Convert string to uppercase for comparison std::string upper(value); std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper); if (upper == "BACK") return RenderState::CULL_FACE_SIDE_BACK; else if (upper == "FRONT") return RenderState::CULL_FACE_SIDE_FRONT; else if (upper == "FRONT_AND_BACK") return RenderState::CULL_FACE_SIDE_FRONT_AND_BACK; else { GP_ERROR("Unsupported cull face side value (%s). Will default to BACK if errors are treated as warnings)", value); return RenderState::CULL_FACE_SIDE_BACK; } }
void Matrix::createLookAt(float eyePositionX, float eyePositionY, float eyePositionZ, float targetPositionX, float targetPositionY, float targetPositionZ, float upX, float upY, float upZ, Matrix* dst) { GP_ASSERT(dst); Vector3 eye(eyePositionX, eyePositionY, eyePositionZ); Vector3 target(targetPositionX, targetPositionY, targetPositionZ); Vector3 up(upX, upY, upZ); up.normalize(); Vector3 zaxis; Vector3::subtract(eye, target, &zaxis); zaxis.normalize(); Vector3 xaxis; Vector3::cross(up, zaxis, &xaxis); xaxis.normalize(); Vector3 yaxis; Vector3::cross(zaxis, xaxis, &yaxis); yaxis.normalize(); dst->m[0] = xaxis.x; dst->m[1] = yaxis.x; dst->m[2] = zaxis.x; dst->m[3] = 0.0f; dst->m[4] = xaxis.y; dst->m[5] = yaxis.y; dst->m[6] = zaxis.y; dst->m[7] = 0.0f; dst->m[8] = xaxis.z; dst->m[9] = yaxis.z; dst->m[10] = zaxis.z; dst->m[11] = 0.0f; dst->m[12] = -Vector3::dot(xaxis, eye); dst->m[13] = -Vector3::dot(yaxis, eye); dst->m[14] = -Vector3::dot(zaxis, eye); dst->m[15] = 1.0f; }
PhysicsCollisionShape::Definition::Definition(const Definition& definition) { // Bitwise-copy the definition object (equivalent to default copy constructor). memcpy(this, &definition, sizeof(PhysicsCollisionShape::Definition)); // Handle the types that have reference-counted members. switch (type) { case PhysicsCollisionShape::SHAPE_HEIGHTFIELD: if (data.heightfield) data.heightfield->addRef(); break; case PhysicsCollisionShape::SHAPE_MESH: GP_ASSERT(data.mesh); data.mesh->addRef(); break; } }