Exemple #1
0
glm::mat4 getModelTransform(const Json::Value &model_desc) {
  glm::mat4 ret(1.f);
  if (!model_desc.isMember("transform")) {
    return ret;
  }
  Json::Value transform_desc = model_desc["transform"];
  if (transform_desc.isMember("origin")) {
    ret = glm::translate(ret, -toVec3(transform_desc["origin"]));
  }
  if (transform_desc.isMember("up")) {
    glm::vec3 up = glm::normalize(
        toVec3(transform_desc["up"]));
    glm::vec3 forward = glm::normalize(
        toVec3(must_have_idx(transform_desc, "forward")));
    glm::vec3 right = glm::cross(up, forward);
    glm::vec4 cols[] = {
      glm::vec4(forward, 0.f),
      glm::vec4(right, 0.f),
      glm::vec4(up, 0.f),
    };
    for (int i = 0; i < 3; i++) {
      ret[i] = cols[i];
    }
  }
  if (transform_desc.isMember("scale")) {
    ret = glm::scale(ret, glm::vec3(transform_desc["scale"].asFloat()));
  }

  return ret;
}
Exemple #2
0
glm::vec3 Object::nextPosOf(QTProfile* terrain) {
    if (terrain->node == NULL) {
        return glm::vec3(0.0f);
    }
    int using_buffer_data_index = 0;
    glm::vec3 using_buffer_dataNormal = terrain->getResultNormalFromCoord(calcCoordFromPos(position + toVec3(using_vertex_offset)), using_vertex,  &using_buffer_data_index);
    glm::vec3 facePoint_to_pos_vector = position - using_vertex[using_buffer_data_index];
    if (glm::dot(facePoint_to_pos_vector, using_buffer_dataNormal) < 0.0f) {
        position += -velocity * timeStep;
        velocity = glm::reflect(velocity, using_buffer_dataNormal) * 0.9f;
    } else {
        velocity += gravity * timeStep * glm::normalize(-position - toVec3(using_vertex_offset));
        position += velocity * timeStep;
    }
    return position;
}
Exemple #3
0
void renderEntityFromJSON(GameEntity *e, const Json::Value &v) {
  invariant(e, "must have entity to render to");
  if (v.isMember("alive")) {
    for (auto &sample : v["alive"]) {
      e->setAlive(sample[0].asFloat(), sample[1].asBool());
    }
  }
  if (v.isMember("model")) {
    for (auto &sample : v["model"]) {
      e->setModelName(sample[1].asString());
    }
  }
  if (v.isMember("properties")) {
    for (auto &sample : v["properties"]) {
      for (auto &prop : sample[1]) {
        e->addProperty(prop.asInt());
      }
    }
  }
  if (v.isMember("pid")) {
    for (auto &sample : v["pid"]) {
      e->setPlayerID(sample[0].asFloat(), toID(sample[1]));
    }
  }
  if (v.isMember("tid")) {
    for (auto &sample : v["tid"]) {
      e->setTeamID(sample[0].asFloat(), toID(sample[1]));
    }
  }
  if (v.isMember("pos")) {
    for (auto &sample : v["pos"]) {
      e->setPosition(sample[0].asFloat(), toVec2(sample[1]));
    }
  }
  if (v.isMember("size")) {
    for (auto &sample : v["size"]) {
      e->setSize(sample[0].asFloat(), toVec3(sample[1]));
    }
  }
  if (v.isMember("angle")) {
    for (auto &sample : v["angle"]) {
      e->setAngle(sample[0].asFloat(), sample[1].asFloat());
    }
  }
  if (v.isMember("sight")) {
    for (auto &sample : v["sight"]) {
      e->setSight(sample[0].asFloat(), sample[1].asFloat());
    }
  }
  if (v.isMember("visible")) {
    for (auto &sample : v["visible"]) {
      float t = sample[0].asFloat();
      VisibilitySet set;
      for (auto pid : sample[1]) {
        set.insert(toID(pid));
      }
      e->setVisibilitySet(t, set);
    }
  }
  if (v.isMember("actions")) {
    for (auto &sample : v["actions"]) {
      float t = sample[0].asFloat();

      std::vector<UIAction> actions;
      for (auto &action_json : sample[1]) {
        auto uiaction = UIActionFromJSON(action_json);
        uiaction.owner_id = e->getGameID();
        actions.push_back(uiaction);
      }
      if (!actions.empty()) {
        e->setActions(t, actions);
      }
    }
  }
  if (v.isMember("ui_info")) {
    for (auto &&sample : v["ui_info"]) {
      const float t = sample[0].asFloat();
      GameEntity::UIInfo uiinfo = UIInfoFromJSON(sample[1]);
      e->setUIInfo(t, uiinfo);
    }
  }
}
Exemple #4
0
SimpleVec3d SimpleVec3d::rotateBy(SimpleVec3d axis, float angle)
{
	return SimpleVec3d(glm::rotate(toVec3(), angle, axis.toVec3()));
}
Exemple #5
0
Entity SceneLoader::instantiate(Json def, Resources& resources, const string& pathContext)
{
	ASSERT(def.is_object());

	if (def["prefab"].is_string()) {
		const string& prefabName = def["prefab"].string_value();
		auto prefabIter = prefabs.find(prefabName);
		if (prefabIter != prefabs.end()) {
			def = assign(prefabIter->second, def);
		} else if (endsWith(prefabName, ".json")) {
				string err;
				Json extPrefab = Json::parse(resources.getText(resolvePath(pathContext, prefabName), Resources::NO_CACHE), err);
				if (!err.empty()) {
					logError("Failed to parse prefab \"%s\": %s", prefabName.c_str(), err.c_str());
				} else {
					def = assign(extPrefab, def);
					prefabs[prefabName] = extPrefab;
				}
		} else {
			logError("Could not find prefab \"%s\"", prefabName.c_str());
		}
	}

	Entity entity = world->create();

	if (def["name"].is_string()) {
		entity.tag(def["name"].string_value());
#ifdef USE_DEBUG_NAMES
		DebugInfo info;
		info.name = def["name"].string_value();
		entity.add<DebugInfo>(info);
	} else {
		static uint debugId = 0;
		DebugInfo info;
		if (def["prefab"].is_string())
			info.name = def["prefab"].string_value() + "#";
		else if (def["geometry"].is_string())
			info.name = def["geometry"].string_value() + "#";
		else info.name = "object#";
		info.name += std::to_string(debugId++);
		entity.tag(info.name);
		entity.add<DebugInfo>(info);
#endif
	}

	// Parse transform
	if (!def["position"].is_null() || !def["rotation"].is_null() || !def["scale"].is_null() || !def["geometry"].is_null()) {
		Transform transform;
		setVec3(transform.position, def["position"]);
		setVec3(transform.scale, def["scale"]);
		if (!def["rotation"].is_null()) {
			const Json& rot = def["rotation"];
			if (rot.is_array() && rot.array_items().size() == 4)
				transform.rotation = quat(rot[3].number_value(), rot[0].number_value(), rot[1].number_value(), rot[2].number_value());
			else transform.rotation = quat(toVec3(rot));
		}
		entity.add(transform);
	}

	// Parse light
	const Json& lightDef = def["light"];
	if (!lightDef.is_null()) {
		Light light;
		const string& lightType = lightDef["type"].string_value();
		if (lightType == "ambient") light.type = Light::AMBIENT_LIGHT;
		else if (lightType == "point") light.type = Light::POINT_LIGHT;
		else if (lightType == "directional") light.type = Light::DIRECTIONAL_LIGHT;
		else if (lightType == "spot") light.type = Light::SPOT_LIGHT;
		else if (lightType == "area") light.type = Light::AREA_LIGHT;
		else if (lightType == "hemisphere") light.type = Light::HEMISPHERE_LIGHT;
		else logError("Unknown light type \"%s\"", lightType.c_str());
		setColor(light.color, lightDef["color"]);
		if (!def["position"].is_null())
			light.position = toVec3(def["position"]);
		if (!lightDef["direction"].is_null())
			light.direction = toVec3(lightDef["direction"]);
		setNumber(light.distance, lightDef["distance"]);
		setNumber(light.decay, lightDef["decay"]);
		entity.add(light);
		numLights++;
	}

	if (!def["geometry"].is_null()) {
		Model model;
		parseModel(model, def, resources, pathContext);
		entity.add(model);
		numModels++;
	}

	// Patch bounding box
	// TODO: Bounding box is not correct if scale changed at runtime
	if (entity.has<Model>() && entity.has<Transform>()) {
		Model& model = entity.get<Model>();
		const Transform& trans = entity.get<Transform>();
		model.bounds.min = model.lods[0].geometry->bounds.min * trans.scale;
		model.bounds.max = model.lods[0].geometry->bounds.max * trans.scale;
		model.bounds.radius = model.lods[0].geometry->bounds.radius * glm::compMax(trans.scale);
	}

	// Parse body (needs to be after geometry, transform, bounds...)
	if (!def["body"].is_null()) {
		const Json& bodyDef = def["body"];
		ASSERT(bodyDef.is_object());
		ASSERT(entity.has<Model>());
		ASSERT(entity.has<Transform>());
		const Model& model = entity.get<Model>();
		const Transform& transform = entity.get<Transform>();

		float mass = 0.f;
		setNumber(mass, bodyDef["mass"]);

		btCollisionShape* shape = NULL;
		const string& shapeStr = bodyDef["shape"].string_value();
		vec3 extents = model.bounds.max - model.bounds.min;
		if (shapeStr == "box") {
			shape = new btBoxShape(convert(extents * 0.5f));
		} else if (shapeStr == "sphere") {
			shape = new btSphereShape(model.bounds.radius);
		} else if (shapeStr == "cylinder") {
			shape = new btCylinderShape(convert(extents * 0.5f));
		} else if (shapeStr == "capsule") {
			float r = glm::max(extents.x, extents.z) * 0.5f;
			shape = new btCapsuleShape(r, extents.y);
		} else if (shapeStr == "trimesh") {
			Geometry* colGeo = nullptr;
			if (bodyDef["geometry"].is_string()) {
				colGeo = resources.getGeometry(bodyDef["geometry"].string_value());
			} else {
				if (bodyDef["geometry"].is_array())
					logError("LODs not supported for collision mesh.");
				colGeo = model.lods[0].geometry;
			}
			if (!colGeo->collisionMesh)
				colGeo->generateCollisionTriMesh();
			if (mass <= 0.f) { // Static mesh
				shape = new btBvhTriangleMeshShape(colGeo->collisionMesh, true);
			} else {
				shape = new btGImpactMeshShape(colGeo->collisionMesh);
				static_cast<btGImpactMeshShape*>(shape)->updateBound();
			}
		} else {
			logError("Unknown shape %s", shapeStr.c_str());
		}
		ASSERT((shapeStr == "trimesh" || bodyDef["geometry"].is_null()) && "Trimesh shape type required if body.geometry is specified");
		ASSERT(shape);

		btVector3 inertia(0, 0, 0);
		shape->calculateLocalInertia(mass, inertia);

		btRigidBody::btRigidBodyConstructionInfo info(mass, NULL, shape, inertia);
		info.m_startWorldTransform = btTransform(convert(transform.rotation), convert(transform.position));
		setNumber(info.m_friction, bodyDef["friction"]);
		setNumber(info.m_rollingFriction, bodyDef["rollingFriction"]);
		setNumber(info.m_restitution, bodyDef["restitution"]);
		if (bodyDef["noSleep"].bool_value()) {
			info.m_linearSleepingThreshold = 0.f;
			info.m_angularSleepingThreshold = 0.f;
		}
		entity.add<btRigidBody>(info);
		numBodies++;
		btRigidBody& body = entity.get<btRigidBody>();
		if (!bodyDef["angularFactor"].is_null())
			body.setAngularFactor(convert(toVec3(bodyDef["angularFactor"])));
		if (!bodyDef["linearFactor"].is_null())
			body.setLinearFactor(convert(toVec3(bodyDef["linearFactor"])));
		if (bodyDef["noGravity"].bool_value())
			body.setFlags(body.getFlags() | BT_DISABLE_WORLD_GRAVITY);
		body.setUserIndex(entity.get_id());
		if (world->has_system<PhysicsSystem>())
			world->get_system<PhysicsSystem>().add(entity);
	}

	if (!def["animation"].is_null()) {
		ASSERT(entity.has<Model>());
		const Json& animDef = def["animation"];
		BoneAnimation anim;
		setNumber(anim.speed, animDef["speed"]);
		entity.add(anim);
		if (animDef["play"].is_bool() && animDef["play"].bool_value())
			world->get_system<AnimationSystem>().play(entity);
		else world->get_system<AnimationSystem>().stop(entity);
	}

	if (def["trackGround"].bool_value()) {
		ASSERT(entity.has<btRigidBody>());
		entity.add<GroundTracker>();
	}

	if (def["trackContacts"].bool_value()) {
		ASSERT(entity.has<btRigidBody>());
		entity.add<ContactTracker>();
	}

	if (def["triggerVolume"].is_object()) {
		ASSERT(entity.has<Transform>());
		const Json& triggerDef = def["triggerVolume"];
		TriggerVolume& trigger = entity.add<TriggerVolume>();

		setNumber(trigger.times, triggerDef["times"]);
		setNumber(trigger.bounds.radius, triggerDef["radius"]);
		setVec3(trigger.bounds.min, triggerDef["min"]);
		setVec3(trigger.bounds.min, triggerDef["max"]);

		if (triggerDef["receiver"].is_string())
			trigger.receiverModule = id::hash(triggerDef["receiver"].string_value());
		if (triggerDef["enterMessage"].is_string())
			trigger.enterMessage = id::hash(triggerDef["enterMessage"].string_value());
		else if (triggerDef["enterMessage"].is_number())
			trigger.enterMessage = triggerDef["enterMessage"].number_value();
		if (triggerDef["exitMessage"].is_string())
			trigger.exitMessage = id::hash(triggerDef["exitMessage"].string_value());
		else if (triggerDef["exitMessage"].is_number())
			trigger.exitMessage = triggerDef["exitMessage"].number_value();

		if (triggerDef["groups"].is_number())
			trigger.groups = 1 << (uint)triggerDef["groups"].number_value();
		else if (triggerDef["groups"].is_array()) {
			for (const auto& item : triggerDef["groups"].array_items())
				trigger.groups |= 1 << (uint)item.number_value();
		}
	}

	if (def["triggerGroup"].is_number()) {
		ASSERT(entity.has<Transform>());
		entity.add<TriggerGroup>().group = 1 << (uint)def["triggerGroup"].number_value();
	}

	if (!def["moveSound"].is_null()) {
		const Json& soundDef = def["moveSound"];
		MoveSound sound;
		if (soundDef["event"].is_string())
			sound.event = id::hash(soundDef["event"].string_value());
		setNumber(sound.stepLength, soundDef["step"]);
		ASSERT(sound.event);
		ASSERT(entity.has<Transform>());
		sound.prevPos = entity.get<Transform>().position;
		entity.add(sound);
	}

	if (!def["contactSound"].is_null()) {
		const Json& soundDef = def["contactSound"];
		ContactSound sound;
		if (soundDef["event"].is_string())
			sound.event = id::hash(soundDef["event"].string_value());
		ASSERT(sound.event);
		ASSERT(entity.has<Transform>());
		ASSERT(entity.has<ContactTracker>());
		entity.add(sound);
	}

	return entity;
}
Exemple #6
0
osg::Node* createNodeForActor( PxRigidActor* actor )
{
    if ( !actor ) return NULL;
    std::vector<PxShape*> shapes( actor->getNbShapes() );
    
    osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
    transform->setMatrix( toMatrix(PxMat44(actor->getGlobalPose())) );
    
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    transform->addChild( geode.get() );
    
    PxU32 num = actor->getShapes( &(shapes[0]), actor->getNbShapes() );
    for ( PxU32 i=0; i<num; ++i )
    {
        PxShape* shape = shapes[i];
        osg::Matrix localMatrix = toMatrix( PxMat44(actor->getGlobalPose()) );
        osg::Vec3 localPos = toVec3( shape->getLocalPose().p );
        osg::Quat localQuat(shape->getLocalPose().q.x, shape->getLocalPose().q.y,
                            shape->getLocalPose().q.z, shape->getLocalPose().q.w);
        
        switch ( shape->getGeometryType() )
        {
        case PxGeometryType::eSPHERE:
            {
                PxSphereGeometry sphere;
                shape->getSphereGeometry( sphere );
                
                osg::Sphere* sphereShape = new osg::Sphere(localPos, sphere.radius);
                geode->addDrawable( new osg::ShapeDrawable(sphereShape) );
            }
            break;
        case PxGeometryType::ePLANE:
            // TODO
            break;
        case PxGeometryType::eCAPSULE:
            {
                PxCapsuleGeometry capsule;
                shape->getCapsuleGeometry( capsule );
                
                osg::Capsule* capsuleShape = new osg::Capsule(
                    localPos, capsule.radius, capsule.halfHeight * 2.0f);
                capsuleShape->setRotation( localQuat );
                geode->addDrawable( new osg::ShapeDrawable(capsuleShape) );
            }
            break;
        case PxGeometryType::eBOX:
            {
                PxBoxGeometry box;
                shape->getBoxGeometry( box );
                
                osg::Box* boxShape = new osg::Box(localPos,
                    box.halfExtents[0] * 2.0f, box.halfExtents[1] * 2.0f, box.halfExtents[2] * 2.0f);
                boxShape->setRotation( localQuat );
                geode->addDrawable( new osg::ShapeDrawable(boxShape) );
            }
            break;
        case PxGeometryType::eCONVEXMESH:
            {
                PxConvexMeshGeometry convexMeshGeom;
                shape->getConvexMeshGeometry( convexMeshGeom );
                // TODO: consider convexMeshGeom.scale
                
                PxConvexMesh* convexMesh = convexMeshGeom.convexMesh;
                if ( convexMesh )
                {
                    /*for ( unsigned int i=0; i<convexMesh->getNbPolygons(); ++i )
                    {
                        
                    }*/
                    // TODO
                }
            }
            break;
        case PxGeometryType::eTRIANGLEMESH:
            {
                PxTriangleMeshGeometry triangleMeshGeom;
                shape->getTriangleMeshGeometry( triangleMeshGeom );
                // TODO: consider triangleMeshGeom.scale
                
                PxTriangleMesh* triangleMesh = triangleMeshGeom.triangleMesh;
                if ( triangleMesh )
                {
                    osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array( triangleMesh->getNbVertices() );
                    for ( unsigned int i=0; i<va->size(); ++i )
                        (*va)[i] = toVec3( *(triangleMesh->getVertices() + i) ) * localMatrix;
                    
                    osg::ref_ptr<osg::DrawElements> de;
                    if ( triangleMesh->getTriangleMeshFlags()&PxTriangleMeshFlag::eHAS_16BIT_TRIANGLE_INDICES )
                    {
                        osg::DrawElementsUShort* de16 = new osg::DrawElementsUShort(GL_TRIANGLES);
                        de = de16;
                        
                        const PxU16* indices = (const PxU16*)triangleMesh->getTriangles();
                        for ( unsigned int i=0; i<triangleMesh->getNbTriangles(); ++i )
                        {
                            de16->push_back( indices[3 * i + 0] );
                            de16->push_back( indices[3 * i + 1] );
                            de16->push_back( indices[3 * i + 2] );
                        }
                    }
                    else
                    {
                        osg::DrawElementsUInt* de32 = new osg::DrawElementsUInt(GL_TRIANGLES);
                        de = de32;
                        
                        const PxU32* indices = (const PxU32*)triangleMesh->getTriangles();
                        for ( unsigned int i=0; i<triangleMesh->getNbTriangles(); ++i )
                        {
                            de32->push_back( indices[3 * i + 0] );
                            de32->push_back( indices[3 * i + 1] );
                            de32->push_back( indices[3 * i + 2] );
                        }
                    }
                    geode->addDrawable( createGeometry(va.get(), NULL, NULL, de.get()) );
                }
            }
            break;
        case PxGeometryType::eHEIGHTFIELD:
            {
                PxHeightFieldGeometry hfGeom;
                shape->getHeightFieldGeometry( hfGeom );
                // TODO: consider hfGeom.*scale
                
                PxHeightField* heightField = hfGeom.heightField;
                if ( heightField )
                {
                    // TODO
                }
            }
            break;
        }
    }
    return transform.release();
}
Exemple #7
0
kvs::Vec4 RGBAColor::toVec4() const
{
    return kvs::Vec4( toVec3(), m_opacity );
}
Exemple #8
0
Geometry::SRT toSRT(const btTransform& t){
	return Geometry::SRT(toVec3(t.getOrigin()), toMatrix3x3(t.getBasis()),1.0);
}
Exemple #9
0
Geometry::Matrix3x3 toMatrix3x3(const btMatrix3x3& btm){
    Geometry::Matrix3x3 tmp;
    for(int i = 0; i<3; ++i)
        tmp.setRow(i,toVec3(btm.getRow(i)));
    return tmp;
}