Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Python bindings for the Light convenience class #2043

Merged
merged 31 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bd9846e
Adds bindings for the world convenience class
Voldivh Jul 18, 2023
1db3735
Adds initial tests
Voldivh Jul 18, 2023
df9608e
Use alias on bindings
Voldivh Jul 19, 2023
40423f8
Adds test to this class
Voldivh Jul 25, 2023
4a013a6
Adds missing dependency for CI
Voldivh Jul 26, 2023
55e5bb7
Adds dependency to packages.apt
Voldivh Jul 26, 2023
863b61b
Adds newline at the end of file
Voldivh Jul 26, 2023
e7c955b
Renames the world sdf file
Voldivh Jul 27, 2023
cbcdf3d
Adds the rest of the test
Voldivh Aug 1, 2023
aa435d6
Removes trailing whitespace
Voldivh Aug 1, 2023
a97358d
Adds import dependency files
Voldivh Aug 8, 2023
99c9de0
Adds newline at end of files
Voldivh Aug 8, 2023
5414b55
Address reviewer feedback
mjcarroll Jul 18, 2023
d04f3ed
Include correct export header
mjcarroll Jul 18, 2023
c153884
Adds bindings for the Light class
Voldivh Jul 19, 2023
669d75a
Adds test for the bindings
Voldivh Jul 27, 2023
3c41f7f
Modifies test to use the appropiate light types (test failing)
Voldivh Jul 28, 2023
def4604
Remove test for setters methods
Voldivh Aug 1, 2023
be8ec34
Removes trailing whitespace
Voldivh Aug 1, 2023
3f75812
Removes trailing whitespace
Voldivh Aug 1, 2023
d2cf8f6
Modifies import dependencies
Voldivh Aug 8, 2023
4ecc165
Merge branch 'main' into voldivh/python_bindings_light
Voldivh Aug 9, 2023
0abd9b4
Adds copy constructor
Voldivh Aug 10, 2023
1da8f4d
Merge branch 'main' into voldivh/python_bindings_light
Voldivh Aug 15, 2023
fb5e2cf
Modifies the use of the null entity variable
Voldivh Aug 15, 2023
7b75f79
Merge branch 'main' into voldivh/python_bindings_light
Voldivh Aug 21, 2023
5c5f53e
Adds verification test for values after we have set them
Voldivh Aug 22, 2023
209e556
Remove checks that require a rendering system, fix name
azeey Aug 25, 2023
801bb08
Address reviewer feedback
azeey Aug 25, 2023
07b7f78
Merge remote-tracking branch 'origin/main' into voldivh/python_bindin…
azeey Aug 25, 2023
f0732eb
Fix import
azeey Aug 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/gz/sim/Light.hh
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ namespace gz
/// \brief Set attenuation range of this light.
/// \param[in] _ecm Entity-component manager.
/// Light attenuation is not applicable to directional lights.
/// \param[in] _bool True to cast shadows, false to not cast shadows.
/// \param[in] _range Attenuation range value to set.
public: void SetAttenuationRange(EntityComponentManager &_ecm,
double _range);

Expand Down
2 changes: 2 additions & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pybind11_add_module(${BINDINGS_MODULE_NAME} MODULE
src/gz/sim/EntityComponentManager.cc
src/gz/sim/EventManager.cc
src/gz/sim/Joint.cc
src/gz/sim/Light.cc
src/gz/sim/Link.cc
src/gz/sim/Model.cc
src/gz/sim/TestFixture.cc
Expand Down Expand Up @@ -98,6 +99,7 @@ if (BUILD_TESTING)
set(python_tests
actor_TEST
joint_TEST
light_TEST
link_TEST
model_TEST
sensor_TEST
Expand Down
163 changes: 163 additions & 0 deletions python/src/gz/sim/Light.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (C) 2023 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "Light.hh"

namespace py = pybind11;

namespace gz
{
namespace sim
{
namespace python
{
void defineSimLight(py::object module)
{
py::class_<gz::sim::Light>(module, "Light")
.def(py::init<gz::sim::Entity>())
.def(py::init<gz::sim::Light>())
.def("entity", &gz::sim::Light::Entity,
"Get the entity which this light is related to.")
.def("reset_entity", &gz::sim::Light::ResetEntity,
"Reset Entity to a new one.")
.def("valid", &gz::sim::Light::Valid,
py::arg("ecm"),

Check warning on line 41 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L41

Added line #L41 was not covered by tests
"Check whether this light correctly refers to an entity that "
"has a components::Light.")
.def("name", &gz::sim::Light::Name,
py::arg("ecm"),

Check warning on line 45 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L45

Added line #L45 was not covered by tests
"Get the light's unscoped name.")
.def("pose", &gz::sim::Light::Pose,
py::arg("ecm"),

Check warning on line 48 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L48

Added line #L48 was not covered by tests
"Get the pose of the light. "
"The pose is given w.r.t the light's parent. which can be a world or "
"a link.")
.def("type", &gz::sim::Light::Type,
py::arg("ecm"),

Check warning on line 53 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L53

Added line #L53 was not covered by tests
"Get the light type.")
.def("diffuse_color", &gz::sim::Light::DiffuseColor,
py::arg("ecm"),

Check warning on line 56 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L56

Added line #L56 was not covered by tests
"Get the light diffuse color.")
.def("specular_color", &gz::sim::Light::SpecularColor,
py::arg("ecm"),

Check warning on line 59 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L59

Added line #L59 was not covered by tests
"Get the light specular color.")
.def("cast_shadows", &gz::sim::Light::CastShadows,
py::arg("ecm"),

Check warning on line 62 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L62

Added line #L62 was not covered by tests
"Get whether the light casts shadows.")
.def("intensity", &gz::sim::Light::Intensity,
py::arg("ecm"),

Check warning on line 65 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L65

Added line #L65 was not covered by tests
"Get the light intensity.")
.def("direction", &gz::sim::Light::Direction,
py::arg("ecm"),

Check warning on line 68 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L68

Added line #L68 was not covered by tests
"Get the light direction.")
.def("attenuation_range", &gz::sim::Light::AttenuationRange,
py::arg("ecm"),

Check warning on line 71 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L71

Added line #L71 was not covered by tests
"Get the light attenuation range. "
"Light attenuation is not applicable to directional lights.")
.def("attenuation_constant", &gz::sim::Light::AttenuationConstant,
py::arg("ecm"),

Check warning on line 75 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L75

Added line #L75 was not covered by tests
"Get the light attenuation constant value. "
"Light attenuation is not applicable to directional lights.")
.def("attenuation_linear", &gz::sim::Light::AttenuationLinear,
py::arg("ecm"),

Check warning on line 79 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L79

Added line #L79 was not covered by tests
"Get the light attenuation linear value. "
"Light attenuation is not applicable to directional lights.")
.def("attenuation_quadratic", &gz::sim::Light::AttenuationQuadratic,
py::arg("ecm"),

Check warning on line 83 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L83

Added line #L83 was not covered by tests
"Get the light attenuation quadratic value. "
"Light attenuation is not applicable to directional lights.")
.def("spot_inner_angle", &gz::sim::Light::SpotInnerAngle,
py::arg("ecm"),

Check warning on line 87 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L87

Added line #L87 was not covered by tests
"Get the inner angle of light. Applies to spot lights only.")
.def("spot_outer_angle", &gz::sim::Light::SpotOuterAngle,
py::arg("ecm"),

Check warning on line 90 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L90

Added line #L90 was not covered by tests
"Get the outer angle of light. Applies to spot lights only.")
.def("spot_falloff", &gz::sim::Light::SpotFalloff,
py::arg("ecm"),

Check warning on line 93 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L93

Added line #L93 was not covered by tests
"Get the fall off value of light. Applies to spot lights only.")
.def("set_pose", &gz::sim::Light::SetPose,
py::arg("ecm"),
py::arg("pose"),

Check warning on line 97 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L96-L97

Added lines #L96 - L97 were not covered by tests
"Set the pose of this light.")
.def("set_diffuse_color", &gz::sim::Light::SetDiffuseColor,
py::arg("ecm"),
py::arg("color"),

Check warning on line 101 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L100-L101

Added lines #L100 - L101 were not covered by tests
"Set the diffuse color of this light.")
.def("set_specular_color", &gz::sim::Light::SetSpecularColor,
py::arg("ecm"),
py::arg("color"),

Check warning on line 105 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L104-L105

Added lines #L104 - L105 were not covered by tests
"Set the specular color of this light.")
.def("set_cast_shadows", &gz::sim::Light::SetCastShadows,
py::arg("ecm"),
py::arg("cast_shadows"),

Check warning on line 109 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L108-L109

Added lines #L108 - L109 were not covered by tests
"Set whether the light casts shadows.")
.def("set_intensity", &gz::sim::Light::SetIntensity,
py::arg("ecm"),
py::arg("value"),

Check warning on line 113 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L112-L113

Added lines #L112 - L113 were not covered by tests
"Set light intensity.")
.def("set_direction", &gz::sim::Light::SetDirection,
py::arg("ecm"),
py::arg("direction"),

Check warning on line 117 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L116-L117

Added lines #L116 - L117 were not covered by tests
"Set light direction. Applies to directional lights.")
.def("set_attenuation_range", &gz::sim::Light::SetAttenuationRange,
py::arg("ecm"),
py::arg("range"),

Check warning on line 121 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L120-L121

Added lines #L120 - L121 were not covered by tests
"Set attenuation range of this light.")
.def("set_attenuation_constant", &gz::sim::Light::SetAttenuationConstant,
py::arg("ecm"),
py::arg("value"),

Check warning on line 125 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L124-L125

Added lines #L124 - L125 were not covered by tests
"Set attenuation constant value of this light.")
.def("set_attenuation_linear", &gz::sim::Light::SetAttenuationLinear,
py::arg("ecm"),
py::arg("value"),

Check warning on line 129 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L128-L129

Added lines #L128 - L129 were not covered by tests
"Set attenuation linear value of this light.")
.def("set_attenuation_quadratic", &gz::sim::Light::SetAttenuationQuadratic,
py::arg("ecm"),
py::arg("color"),

Check warning on line 133 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L132-L133

Added lines #L132 - L133 were not covered by tests
"Set attenuation quadratic value of this light.")
.def("set_spot_inner_angle", &gz::sim::Light::SetSpotInnerAngle,
py::arg("ecm"),
py::arg("angle"),

Check warning on line 137 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L136-L137

Added lines #L136 - L137 were not covered by tests
"Set inner angle for this light. Applies to spot lights only.")
.def("set_spot_outer_angle", &gz::sim::Light::SetSpotOuterAngle,
py::arg("ecm"),
py::arg("angle"),

Check warning on line 141 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L140-L141

Added lines #L140 - L141 were not covered by tests
"Set outer angle for this light. Applies to spot lights only.")
.def("set_spot_falloff", &gz::sim::Light::SetSpotFalloff,
py::arg("ecm"),
py::arg("falloff"),

Check warning on line 145 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L144-L145

Added lines #L144 - L145 were not covered by tests
"Set fall off value for this light. Applies to spot lights only.")
.def("parent", &gz::sim::Light::Parent,
py::arg("ecm"),

Check warning on line 148 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L148

Added line #L148 was not covered by tests
"Get the parent entity. This can be a world or a link.")
.def("__copy__",
[](const gz::sim::Light &self)

Check warning on line 151 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L151

Added line #L151 was not covered by tests
{
return gz::sim::Light(self);

Check warning on line 153 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L153

Added line #L153 was not covered by tests
})
.def("__deepcopy__",
[](const gz::sim::Light &self, pybind11::dict)

Check warning on line 156 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L156

Added line #L156 was not covered by tests
{
return gz::sim::Light(self);

Check warning on line 158 in python/src/gz/sim/Light.cc

View check run for this annotation

Codecov / codecov/patch

python/src/gz/sim/Light.cc#L158

Added line #L158 was not covered by tests
});
}
} // namespace python
} // namespace sim
} // namespace gz
40 changes: 40 additions & 0 deletions python/src/gz/sim/Light.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2023 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef GZ_SIM_PYTHON__LIGHT_HH_
#define GZ_SIM_PYTHON__LIGHT_HH_

#include <pybind11/pybind11.h>

#include <gz/sim/Light.hh>

namespace gz
{
namespace sim
{
namespace python
{
/// Define a pybind11 wrapper for a gz::sim::Light
/**
* \param[in] module a pybind11 module to add the definition to
*/
void
defineSimLight(pybind11::object module);
} // namespace python
} // namespace sim
} // namespace gz

#endif // GZ_SIM_PYTHON__LIGHT_HH_
2 changes: 0 additions & 2 deletions python/src/gz/sim/Link.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <iostream>

#include "Link.hh"

namespace py = pybind11;
Expand Down
2 changes: 2 additions & 0 deletions python/src/gz/sim/_gz_sim_pybind11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "EntityComponentManager.hh"
#include "EventManager.hh"
#include "Joint.hh"
#include "Light.hh"
#include "Link.hh"
#include "Model.hh"
#include "Sensor.hh"
Expand All @@ -39,6 +40,7 @@ PYBIND11_MODULE(BINDINGS_MODULE_NAME, m) {
gz::sim::python::defineSimEntityComponentManager(m);
gz::sim::python::defineSimEventManager(m);
gz::sim::python::defineSimJoint(m);
gz::sim::python::defineSimLight(m);
gz::sim::python::defineSimLink(m);
gz::sim::python::defineSimModel(m);
gz::sim::python::defineSimSensor(m);
Expand Down
125 changes: 125 additions & 0 deletions python/test/light_TEST.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/usr/bin/env python3
# Copyright (C) 2023 Open Source Robotics Foundation

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import unittest

from gz_test_deps.common import set_verbosity
from gz_test_deps.sim import (K_NULL_ENTITY, Light,
TestFixture, World, world_entity)
from gz_test_deps.math import Angle, Color, Pose3d, Vector3d


# This class test the Light class API created with pybind11. Since the setters
# methods require other systems to work (eg. Rendering sensors), those methods
# will not be fully tested, just verifying the method is being called.
class TestLight(unittest.TestCase):
post_iterations = 0
iterations = 0
pre_iterations = 0

def test_light(self):
set_verbosity(4)

file_path = os.path.dirname(os.path.realpath(__file__))
fixture = TestFixture(os.path.join(file_path, 'light_test.sdf'))

def on_post_udpate_cb(_info, _ecm):
self.post_iterations += 1

def on_pre_udpate_cb(_info, _ecm):
self.pre_iterations += 1
world_e = world_entity(_ecm)
self.assertNotEqual(K_NULL_ENTITY, world_e)
w = World(world_e)
light_point = Light(w.light_by_name(_ecm, 'light_point_test'))
light_dir = Light(w.light_by_name(_ecm, 'light_directional_test'))
light_spot = Light(w.light_by_name(_ecm, 'light_spot_test'))
# Entity Test
self.assertNotEqual(K_NULL_ENTITY, light_point.entity())
self.assertNotEqual(K_NULL_ENTITY, light_dir.entity())
self.assertNotEqual(K_NULL_ENTITY, light_spot.entity())
# Valid Test
self.assertTrue(light_point.valid(_ecm))
self.assertTrue(light_dir.valid(_ecm))
self.assertTrue(light_spot.valid(_ecm))
# Name Test
self.assertEqual('light_point_test', light_point.name(_ecm))
self.assertEqual('light_directional_test', light_dir.name(_ecm))
self.assertEqual('light_spot_test', light_spot.name(_ecm))
# Pose Test
self.assertEqual(Pose3d(0, 2, 2, 0, 0, 0), light_point.pose(_ecm))
light_point.set_pose(_ecm, Pose3d(4, 2, 2, 0, 0, 0))
# Type Test
self.assertEqual('point', light_point.type(_ecm))
self.assertEqual('directional', light_dir.type(_ecm))
self.assertEqual('spot', light_spot.type(_ecm))
# Diffuse Color Test
self.assertEqual(Color(1, 0, 0, 1),
light_point.diffuse_color(_ecm))
light_point.set_diffuse_color(_ecm, Color(1, 1, 0, 1))
azeey marked this conversation as resolved.
Show resolved Hide resolved
# Specular Color Test
self.assertEqual(Color(0.2, 0, 0, 1),
light_point.specular_color(_ecm))
light_point.set_specular_color(_ecm, Color(0.2, 0.2, 0, 1))
# Cast Shadows Test
self.assertTrue(light_point.cast_shadows(_ecm))
light_point.set_cast_shadows(_ecm, False)
# Intensity Test
self.assertEqual(2, light_point.intensity(_ecm))
light_point.set_intensity(_ecm, 5)
# Direction Test
self.assertEqual(Vector3d(0.5, 0.5, -1), light_dir.direction(_ecm))
light_dir.set_direction(_ecm, Vector3d(1, 0, -1))
# Attenuation Range Test
self.assertEqual(20, light_point.attenuation_range(_ecm))
light_point.set_attenuation_range(_ecm, 30)
# Attenuation Constant Test
self.assertEqual(0.8, light_point.attenuation_constant(_ecm))
light_point.set_attenuation_constant(_ecm, 1.2)
# Attenuation Linear Test
self.assertEqual(0.2, light_point.attenuation_linear(_ecm))
light_point.set_attenuation_linear(_ecm, 0.5)
# Attenuation Quadratric Test
self.assertEqual(0.01, light_point.attenuation_quadratic(_ecm))
light_point.set_attenuation_quadratic(_ecm, 0.05)
# Spot Inner Angle Test
self.assertEqual(Angle(10), light_spot.spot_inner_angle(_ecm))
light_spot.set_spot_inner_angle(_ecm, Angle(15))
# Spot Outer Angle Test
self.assertEqual(Angle(5), light_spot.spot_outer_angle(_ecm))
light_spot.set_spot_outer_angle(_ecm, Angle(10))
# Spot Falloff Test
self.assertEqual(2, light_spot.spot_falloff(_ecm))
light_spot.set_spot_falloff(_ecm, 4)

def on_udpate_cb(_info, _ecm):
self.iterations += 1

fixture.on_post_update(on_post_udpate_cb)
fixture.on_update(on_udpate_cb)
fixture.on_pre_update(on_pre_udpate_cb)
fixture.finalize()

server = fixture.server()
server.run(True, 2, False)

self.assertEqual(2, self.pre_iterations)
self.assertEqual(2, self.iterations)
self.assertEqual(2, self.post_iterations)


if __name__ == '__main__':
unittest.main()
Loading