182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten/* 282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * you may not use this file except in compliance with the License. 682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * You may obtain a copy of the License at 782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 1082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Unless required by applicable law or agreed to in writing, software 1182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * See the License for the specific language governing permissions and 1482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * limitations under the License. 1582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten */ 1682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 1782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten/* 3DLocation implementation */ 1882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 1982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten#include "sles_allinclusive.h" 2082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 21f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 22437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenstatic SLresult I3DLocation_SetLocationCartesian(SL3DLocationItf self, const SLVec3D *pLocation) 2382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 24f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 25f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 26f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (NULL == pLocation) { 27f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 28f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 2950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 30f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SLVec3D locationCartesian = *pLocation; 3150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 3250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian = locationCartesian; 3350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 3450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 35f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 36f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 37f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 38f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 3982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 4082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 41f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 4282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic SLresult I3DLocation_SetLocationSpherical(SL3DLocationItf self, 4382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance) 4482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 45f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 46f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 47437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten if (!((-360000 <= azimuth) && (azimuth <= 360000) && 48437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten (-90000 <= elevation) && (elevation <= 90000) && 49f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten (0 <= distance) && (distance <= SL_MILLIMETER_MAX))) { 50f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 51f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 5250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 5350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 5450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationSpherical.mAzimuth = azimuth; 5550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationSpherical.mElevation = elevation; 5650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationSpherical.mDistance = distance; 5750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_UNKNOWN_SPHERICAL_SET; 5850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 59f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 60f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 61f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 62f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 6382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 6482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 65f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 6682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic SLresult I3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement) 6782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 68f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 69f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 70f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (NULL == pMovement) { 71f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 72f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 7350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 74f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SLVec3D movementCartesian = *pMovement; 7550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 76f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten for (;;) { 7750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten enum CartesianSphericalActive locationActive = thiz->mLocationActive; 78f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten switch (locationActive) { 79f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_COMPUTED_SPHERICAL_SET: 80f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_COMPUTED: // not in 1.0.1 81f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_REQUESTED: // not in 1.0.1 82f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_UNKNOWN: 8350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.x += movementCartesian.x; 8450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.y += movementCartesian.y; 8550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.z += movementCartesian.z; 8650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 87f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten break; 88f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_UNKNOWN_SPHERICAL_SET: 8950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_REQUESTED_SPHERICAL_SET; 90f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten // fall through 91f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_REQUESTED_SPHERICAL_SET: 92f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten // matched by cond_broadcast in case multiple requesters 93f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#if 0 9450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_cond_wait(thiz); 95f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#else 9650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_COMPUTED_SPHERICAL_SET; 97f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#endif 98f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten continue; 99f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten default: 100f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten assert(SL_BOOLEAN_FALSE); 101f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten break; 102f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 10382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten break; 10482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten } 10550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 106f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 10782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten } 108f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 109f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 11082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 11182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 112f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 113437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenstatic SLresult I3DLocation_GetLocationCartesian(SL3DLocationItf self, SLVec3D *pLocation) 11482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 115f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 116f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 117f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (NULL == pLocation) { 118f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 119f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 12050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 12150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 122f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten for (;;) { 12350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten enum CartesianSphericalActive locationActive = thiz->mLocationActive; 124f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten switch (locationActive) { 125f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_COMPUTED_SPHERICAL_SET: 126f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_COMPUTED: // not in 1.0.1 127f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_REQUESTED: // not in 1.0.1 128f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_SET_SPHERICAL_UNKNOWN: 129f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten { 13050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten SLVec3D locationCartesian = thiz->mLocationCartesian; 13150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 132f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten *pLocation = locationCartesian; 133f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 134f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten break; 135f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_UNKNOWN_SPHERICAL_SET: 13650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_REQUESTED_SPHERICAL_SET; 137f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten // fall through 138f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten case CARTESIAN_REQUESTED_SPHERICAL_SET: 139f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten // matched by cond_broadcast in case multiple requesters 140f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#if 0 14150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_cond_wait(thiz); 142f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#else 14350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_COMPUTED_SPHERICAL_SET; 144f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#endif 145f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten continue; 146f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten default: 147f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten assert(SL_BOOLEAN_FALSE); 14850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 149f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten pLocation->x = 0; 150f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten pLocation->y = 0; 151f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten pLocation->z = 0; 152f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten break; 15382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten } 15482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten break; 15582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten } 156f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 15782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten } 158f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 159f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 16082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 16182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 162f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 16382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic SLresult I3DLocation_SetOrientationVectors(SL3DLocationItf self, 16482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten const SLVec3D *pFront, const SLVec3D *pAbove) 16582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 166f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 167f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 168f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (NULL == pFront || NULL == pAbove) { 169f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 170f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 171f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SLVec3D front = *pFront; 172f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SLVec3D above = *pAbove; 173f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten // NTH Check for vectors close to zero or close to parallel 17450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 17550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 17650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationVectors.mFront = front; 17750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationVectors.mAbove = above; 17850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationActive = ANGLES_UNKNOWN_VECTORS_SET; 17950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 18050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 181f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 182f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 183f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 184f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 18582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 18682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 187f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 18882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic SLresult I3DLocation_SetOrientationAngles(SL3DLocationItf self, 18982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll) 19082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 191f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 192f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 193437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten if (!((-360000 <= heading) && (heading <= 360000) && 194437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten (-90000 <= pitch) && (pitch <= 90000) && 195f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten (-360000 <= roll) && (roll <= 360000))) { 196f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 197f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 19850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 19950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 20050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mHeading = heading; 20150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mPitch = pitch; 20250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mRoll = roll; 20350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN; 20450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 20550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 206f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 207f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 208f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 209f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 21082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 21182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 212f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 213437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenstatic SLresult I3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta, const SLVec3D *pAxis) 21482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 215f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 216f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 217f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (!((-360000 <= theta) && (theta <= 360000)) || (NULL == pAxis)) { 218f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 219f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 220f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SLVec3D axis = *pAxis; 221f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten // NTH Check that axis is not (close to) zero vector, length does not matter 22250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 22350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 22450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten while (thiz->mRotatePending) 225f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#if 0 22650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_cond_wait(thiz); 227f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#else 228f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten break; 229f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#endif 23050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mTheta = theta; 23150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mAxis = axis; 23250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mRotatePending = SL_BOOLEAN_TRUE; 23350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 234f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 235f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 236f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 237f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 23882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 23982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 240f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 24182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic SLresult I3DLocation_GetOrientationVectors(SL3DLocationItf self, 24282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten SLVec3D *pFront, SLVec3D *pUp) 24382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 244f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 245f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 246f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten if (NULL == pFront || NULL == pUp) { 247f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 248f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } else { 24950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 25050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_shared(thiz); 25150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten SLVec3D front = thiz->mOrientationVectors.mFront; 25250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten SLVec3D up = thiz->mOrientationVectors.mUp; 25350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_shared(thiz); 254f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten *pFront = front; 255f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten *pUp = up; 256f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 257f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten } 258f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 259f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 26082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 26182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 262f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 26382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenstatic const struct SL3DLocationItf_ I3DLocation_Itf = { 26482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_SetLocationCartesian, 26582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_SetLocationSpherical, 26682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_Move, 26782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_GetLocationCartesian, 26882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_SetOrientationVectors, 26982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_SetOrientationAngles, 27082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_Rotate, 27182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten I3DLocation_GetOrientationVectors 27282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten}; 27382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 27482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenvoid I3DLocation_init(void *self) 27582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 27650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten I3DLocation *thiz = (I3DLocation *) self; 27750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mItf = &I3DLocation_Itf; 27850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.x = 0; 27950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.y = 0; 28050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationCartesian.z = 0; 28150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten memset(&thiz->mLocationSpherical, 0x55, sizeof(thiz->mLocationSpherical)); 28250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 28350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mHeading = 0; 28450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mPitch = 0; 28550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationAngles.mRoll = 0; 28650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten memset(&thiz->mOrientationVectors, 0x55, sizeof(thiz->mOrientationVectors)); 28750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN; 28850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mTheta = 0x55555555; 28950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mAxis.x = 0x55555555; 29050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mAxis.y = 0x55555555; 29150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mAxis.z = 0x55555555; 29250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 29382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 294